2011-11-18 74 views
5

我遇到了sql查詢的麻煩。如果同一行不存在,我需要插入一行。這是我到目前爲止有:sql - 插入如果不存在

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; 

我不會很熟悉SQL尤其是不存在的語法,所以當我執行我得到以下錯誤:

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

then and or

符號「然後」被替換爲「INSERT」以繼續。

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 

回答

12

完成所有的SQL,而不是上下文切換到PL/SQL:(?Oracle專用)

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'通常不是原子的,這意味着可以在存在檢查和插入之間插入衝突記錄。 –

+0

@M_M - Oracle中的SQL語句始終是原子的。如果沒有唯一索引,則可能最終導致衝突,因爲插入的另一個會話沒有看到該行,因爲第一個會話尚未提交。 –

+0

我不能說Oracle在這裏的行爲,但會聽取你的意見。我知道一些DBMS將'IF EXISTS(...)THEN'和'INSERT INTO'視爲兩個語句,而不是一個,但它也取決於事務隔離級別等。 –

1

你忘了THEN

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

一個更好的解決方案可能成爲MERGE聲明。

在這裏看到一個很好的解釋,舉例:

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

希望有所幫助。

+1

'MERGE'不是Oracle特有的。它實際上是'SQL:2008'的一部分。例如,[DB2](http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0010873.html)(至少自v9 for z/OS,和9.5 for LUW)和[SQL Server](http://technet.microsoft.com/en-us/library/bb510625.aspx),自2008年以來。 – bhamby

+0

謝謝galador,我很漂亮特別是甲骨文的人,所以我不確定MERGE是SQL標準還是Oracle擴展。感謝您的澄清。 –

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;