2011-11-18 84 views
5

Tôi đang gặp sự cố với truy vấn sql. Tôi cần chèn một hàng nếu cùng một hàng không tồn tại. Đây là những gì tôi có cho đến nay:sql - chèn nếu không tồn tại

DECLARE 
BEGIN 
    FOR FOLDER_ROW IN (SELECT FOLDERID, USERID FROM DATA1.FOLDERS) 
     LOOP      
      IF NOT EXISTS (SELECT * FROM DATA1.FOLDER_USER WHERE FOLDER_ID = FOLDER_ROW.FOLDERID AND USER_ID = FOLDER_ROW.USERID) 
      INSERT INTO DATA1.FOLDER_USER (FOLDER_ID, USER_ID) VALUES (FOLDER_ROW.FOLDERID, FOLDER_ROW.USERID); 
    END LOOP; 
    COMMIT; 
END; 

tôi sẽ không rất quen thuộc với sql đặc biệt là không tồn tại cú pháp như vậy khi tôi thực hiện tôi nhận được lỗi sau:

ORA-06550: line 37, column 11: PLS-00103: Encountered the symbol "INSERT" when expecting one of the following:

then and or

Biểu tượng "sau đó" đã được thay thế cho "INSERT" để tiếp tục.

ORA-06550: line 38, column 10: 
PLS-00103: Encountered the symbol "LOOP" when expecting one of the following: 

    if 
ORA-06550: line 40, column 5: 
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: 

    end not pragma final instantiable order overriding static 
    member constructor map 

Trả lời

12

làm tất cả trong SQL chứ không phải là bối cảnh chuyển đổi thành PL/SQL: (? Oracle cụ thể)

INSERT INTO DATA1.FOLDERS 
(folder_id, 
user_id) 
SELECT f1.folder_id, 
     f1.user_id 
    FROM DATA1.FOLDERS f1 
WHERE NOT EXISTS (SELECT 1 
        FROM DATA1.FOLDERS f2 
        WHERE f1.folder_id = f2.folder_id 
         AND f1.user_id = f2.user_id); 
+1

++ 1 'IF EXISTS() ... INSERT' thường không phải là nguyên tử, có nghĩa là một bản ghi xung đột có thể được chèn vào giữa kiểm tra sự tồn tại và chèn. –

+0

@M_M - Một câu lệnh SQL trong Oracle luôn luôn là nguyên tử. Nếu không có chỉ mục duy nhất, bạn có thể kết thúc với các xung đột vì một phiên khác được chèn không thấy hàng bởi vì phiên đầu tiên chưa cam kết. –

+0

Tôi không thể nói chuyện với hành vi của Oracle ở đây, nhưng sẽ nhận lời của bạn cho nó. Tôi biết một số DBMS xử lý 'NẾU EXISTS (...) THEN' và' INSERT INTO' là hai câu lệnh, không phải là một, nhưng nó phụ thuộc vào mức cô lập giao dịch và tương tự. –

1

Bạn quên THEN

IF condition THEN 
    ... 
ELSE 
    ... 
END IF; 
2

Một giải pháp tốt hơn có thể là báo cáo MERGE.

Xem ở đây cho một lời giải thích tốt đẹp, với các ví dụ:

http://www.oracle-base.com/articles/10g/MergeEnhancements10g.php

Hy vọng rằng sẽ giúp.

+1

'MERGE' không phải là Oracle cụ thể. Nó thực sự là một phần của 'SQL: 2008'. Ví dụ: [DB2] (http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0010873.html) (ít nhất kể từ v9 cho z/OS, và 9.5 cho LUW) và [SQL Server] (http://technet.microsoft.com/en-us/library/bb510625.aspx), kể từ năm 2008. – bhamby

+0

Cảm ơn galador, tôi khá nhiều độc quyền một anh chàng Oracle, vì vậy tôi đã không chắc chắn nếu MERGE là tiêu chuẩn SQL hoặc mở rộng Oracle. Cảm ơn bạn đã làm rõ. –

0
DECLARE 
    N_COUNTS NUMBER; 
BEGIN 
    select count(ID) into N_COUNTS from TABLE_NAME where ID = 1; 
    IF N_COUNTS=0 THEN 
     INSERT QUERY.... 
    ELSE 
     UPDATE QUERY.... 
    END IF; 
END; 
Các vấn đề liên quan