2013-05-19 50 views
15

Tôi có một cơ sở dữ liệu được cập nhật với bộ dữ liệu theo thời gian. Ở đây có thể xảy ra rằng tập dữ liệu được phân phối đã tồn tại trong cơ sở dữ liệu.Thực hiện INSERT có điều kiện với SQL?

Hiện nay tôi đang đầu tiên làm một

SELECT FROM ... WHERE val1=... AND val2=... 

để kiểm tra, nếu một tập dữ liệu với những dữ liệu này đã tồn tại (sử dụng các dữ liệu trong ĐÂU-tuyên bố). Nếu điều này không trả lại bất kỳ giá trị nào, tôi sẽ thực hiện INSERT của tôi.

Nhưng điều này có vẻ hơi phức tạp đối với tôi. Vì vậy, câu hỏi của tôi: là có một số loại INSERT có điều kiện thêm một tập dữ liệu mới chỉ trong trường hợp nó không tồn tại?

Tôi đang sử dụng SmallSQL

+6

*** GÌ *** hệ thống cơ sở dữ liệu này là gì? SQL chỉ là ngôn ngữ truy vấn - được sử dụng bởi nhiều sản phẩm cơ sở dữ liệu. SQL là ** không ** sản phẩm cơ sở dữ liệu trong chính nó. Vì vậy, hãy cho chúng tôi biết nếu bạn đang sử dụng MySQL, Postgres, Oracle, IBM DB2, SQL Server, Firebird - hoặc bất kỳ thứ gì khác có thể ... –

+1

Bạn đang nói về [Hợp nhất/Upsert] (http: // vi. wikipedia.org/wiki/Merge_(SQL))? –

+0

@Elmi: Có bất kỳ câu trả lời nào bên dưới giải quyết vấn đề của bạn không? – DougM

Trả lời

17

Bạn có thể làm điều đó với một tuyên bố duy nhất và một subquery trong gần như tất cả cơ sở dữ liệu quan hệ.

INSERT INTO targetTable(field1) 
SELECT field1 
FROM myTable 
WHERE NOT(field1 IN (SELECT field1 FROM targetTable)) 

Một số cơ sở dữ liệu quan hệ nhất định đã cải thiện cú pháp ở trên vì những gì bạn mô tả là một nhiệm vụ khá phổ biến. SQL Server có cú pháp MERGE với tất cả các tùy chọn và MySQL có cú pháp tùy chọn INSERT OR IGNORE.

Chỉnh sửa:SmallSQL's documentation tương đối thưa thớt như những phần nào của tiêu chuẩn SQL mà nó triển khai. Nó có thể không thực hiện các truy vấn phụ, và như vậy bạn có thể không làm theo lời khuyên trên, hoặc bất cứ nơi nào khác, nếu bạn cần phải gắn bó với SmallSQL.

+0

Nếu bạn đang sử dụng 'INSERT ... VALUES ('a,' 'b,' 'c')', chỉ cần thay đổi câu lệnh của bạn thành 'INSERT ... SELECT 'a', 'b', 'c' WHERE ... 'không có dấu ngoặc đơn. – Noumenon

10

Tôi không biết về SmallSQL, nhưng hoạt động này cho MSSQL:

IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue') 
    UPDATE Table1 SET (...) WHERE Column1='SomeValue' 
ELSE 
    INSERT INTO Table1 VALUES (...) 

Dựa trên những nơi điều kiện, điều này sẽ cập nhật hàng nếu nó tồn tại, khác nó sẽ chèn một cái mới.

Tôi hy vọng đó là những gì bạn đang tìm kiếm.

+4

Tôi không nghĩ rằng 'IF' là một phần của tiêu chuẩn SQL – Andomar

+0

OK cảm ơn. Thay đổi nó thành "MSSQL" –

+0

Đây là lần đầu tiên tôi vui vì chủ nhân hiện tại của tôi sử dụng cơ sở dữ liệu MSSQL. – Cheeku

0

Nếu bạn đang tìm kiếm để làm một "upsert" một trong những cách hiệu quả nhất hiện nay trong SQL Server cho các hàng đơn là thế này:

UPDATE myTable ... 


IF @@ROWCOUNT=0 
    INSERT INTO myTable .... 

Bạn cũng có thể sử dụng cú pháp MERGE nếu bạn đang thực hiện việc này với tập hợp dữ liệu thay vì các hàng đơn lẻ.

Nếu bạn muốn INSERT và không UPDATE sau đó bạn chỉ có thể viết INSERT tuyên bố duy nhất của bạn và sử dụng WHERE NOT EXISTS (SELECT ...)

1

Có thể với điều kiện là EXISTS. WHERE EXISTS kiểm tra sự tồn tại của bất kỳ bản ghi nào trong truy vấn phụ. EXISTS trả về true nếu truy vấn phụ trả về một hoặc nhiều bản ghi. Dưới đây là ví dụ

UPDATE TABLE_NAME 
SET val1=arg1 , val2=arg2 
WHERE NOT EXISTS 
    (SELECT FROM TABLE_NAME WHERE val1=arg1 AND val2=arg2) 
Các vấn đề liên quan