2010-01-13 25 views
5

Tôi đang cố chèn một hàng có thể có hoặc chưa tồn tại. Tôi muốn tránh chọn nó trước và/hoặc nhận được -803 nếu nó tồn tại. Tôi đã thực hiện một số nghiên cứu và đã thử cả hai bỏ qua và tuyên bố hợp nhất, nhưng tiếp tục nhận được lỗi cú pháp trên cả hai. Trong mọi trường hợp, tôi không cố gắng sao chép dữ liệu từ một bảng khác - vì vậy, hợp nhất không thực sự thích hợp.
Không có cách nào trong SQL DB2 chỉ phát hành một chèn không bị lỗi và không phải mã hóa xung quanh điều này? Nói cách khác, có một số cú pháp chèn đảm bảo dữ liệu sẽ được thêm vào nếu nó không tồn tại hoặc sẽ trả lại trạng thái bằng không ngay cả khi nó không?Cố gắng tránh -803 trong DB2 chèn

Trả lời

2

Tóm lại, câu trả lời là không. Trong thời gian dài, tất cả phụ thuộc vào các ràng buộc bạn đã thiết lập trên bảng của bạn. Nếu bạn cố gắng thực hiện một chèn vào một bảng có ràng buộc duy nhất trên một cột và dữ liệu đã tồn tại mà bạn đang cố chèn, bạn sẽ gặp lỗi trong DB2 (và bất kỳ RDBMS nào khác).

Trong trường hợp này, tùy chọn tốt nhất của bạn có thể là viết một thủ tục lưu sẵn để kiểm tra xem bản ghi đã tồn tại chưa trước khi tạo.

+2

Tốt hơn: Đừng lãng phí thời gian kiểm tra sự tồn tại, có quy trình lưu trữ chèn và chỉ xử lý lỗi -803 (SQL0803N). Thậm chí tốt hơn: Chỉ cần có ứng dụng kiểm tra mã trả về từ chèn và xử lý lỗi -803. –

+0

Cảm ơn bạn đã phản hồi nhanh. Tôi đã hy vọng DB2 có một số tương đương với tham số "bỏ qua", nhưng không có may mắn như vậy. Mike –

+0

Đã cố gắng xử lý -803 và thực hiện cập nhật, nhưng điều này để lại một dấu vết ngăn xếp trong nhật ký ngay cả khi quá trình tổng thể thành công, khiến người khác đặt câu hỏi.Vì vậy, tôi đang thay đổi mã để thực hiện kiểm tra sự tồn tại trước tiên. Cảm ơn tất cả những lời đề nghị. –

7

MERGE thích hợp, vì bạn có thể cung cấp động giá trị trong mệnh đề USING (xem ví dụ 5 trong http://publib.boulder.ibm.com/infocenter/db2luw/v9/index.jsp?topic=/com.ibm.db2.udb.admin.doc/doc/r0010873.htm).

Nhưng MERGE là một tính năng V8.2 của DB2! Có thể bạn đang sử dụng V8.1, phải không?

Nếu bạn thực hiện việc kiểm tra sự tồn tại như thế này:

SELECT 
if (found) UPDATE else INSERT 

hãy cẩn thận các vấn đề đồng thời: Hai chủ đề đồng thời có thể cả hai tìm thấy không có cột và sau đó cả hai cố gắng chèn, thậm chí nếu có một giao dịch xung quanh mã ở trên. Để đảm bảo điều này sẽ không xảy ra, bạn cần có khóa cập nhật với Đọc lặp lại trong câu lệnh SELECT ở trên sử dụng WITH RR USE AND KEEP UPDATE LOCKS.

+0

Các sự cố đồng thời vẫn là một vấn đề nếu bạn thực hiện 'INSERT', bắt' -803' và sau đó thực hiện 'UPDATE'? –

2

Bạn có thể thực hiện báo cáo cập nhật, nếu điều đó trả về 0 kết quả được cập nhật, sau đó thực hiện lệnh chèn.

2

Bạn có thể làm điều này bằng cách sử dụng bảng sysibm.sysdummy (hoặc tên tốt hơn là kép từ Oracle hoặc các phiên bản sau của DB2). Điều này sẽ làm việc rất tốt cho trường hợp bạn muốn chèn một hàng không tồn tại nhưng trả về 0 nếu nó tồn tại. AFAIK, bạn không thể cập nhật một hàng bằng cách sử dụng phương pháp này, bạn sẽ cần phải sử dụng hợp nhất cho điều đó.

Để thực hiện việc này, bạn sẽ cần một khóa chính hoặc duy nhất trên bàn của mình. Bạn chèn vào bảng, chọn tất cả các giá trị của bạn từ kép trong quá trình mà một hàng không tồn tại trong bảng của bạn khớp với chỉ mục chính hoặc duy nhất của bạn.

insert into table (column1, column2, column3, column4, column5) 
select 'A', 'B', 'C', 'D', 'E' from dual where not exists (select * from table where column1 = 'A'); 

Tôi thấy điều này rất hữu ích cho các trường hợp tôi có nhiều quy trình chèn vào bảng và tôi không thể đảm bảo thứ tự của các phụ trang đó. Bạn có thể phát hiện xem chèn có thành công hay không bằng giá trị trả về, giá trị này sẽ là 1 nếu thành công hoặc 0 nếu không

Các vấn đề liên quan