2012-04-26 93 views
1

當我執行幾次我插入我的數據好幾次,但我想我的要求我只有一次插入我的數據我有這樣的要求插入請求

INSERT INTO SERVICEPAYANT_CLIENT (RE_ID, TYPE_DONNEES) 
SELECT CLIENT_ID, 160 AS TYPE_DONNEES 
FROM REFERENTIEL r, CLIENT_APPLICATIF ca 
WHERE r.ID = ca.ID_REFERENTIEL 
AND r.TYPE=1 
GROUP BY CLIENT_ID 
HAVING COUNT(*)>0; 

。 如果我的數據不在我的表格中,我想插入我的數據。 謝謝你的幫助。

+0

http://stackoverflow.com/q/108403/284240 – 2012-04-26 14:11:03

回答

2

你可以這樣做:

INSERT INTO SERVICEPAYANT_CLIENT (RE_ID, TYPE_DONNEES) 
SELECT CLIENT_ID, 160 AS TYPE_DONNEES 
FROM REFERENTIEL r, CLIENT_APPLICATIF ca 
WHERE r.ID = ca.ID_REFERENTIEL 
AND r.TYPE=1 
AND NOT EXISTS (
    SELECT * FROM SERVICEPAYANT_CLIENT sp 
    WHERE sp.RE_ID = CLIENT_ID AND TYPE_DONNEES = 160) 
GROUP BY CLIENT_ID 
HAVING COUNT(*)>0; 

的「AND NOT EXISTS ......」是什麼限制了回國已經不是你的目標表行。

1

典型的解決方案是使用由定義記錄的字段組成的唯一約束在數據庫中執行它。你的Java代碼會從數據庫中得到一個錯誤,讓你知道它已經存在。

+1

+1。我打算在運行該SQL腳本之前添加一個「if exists」子句,但是它會因數據庫而容易出現語法錯誤,更重要的是,無論如何它都不能被插入多次,並且它是數據庫的工作來執行,而不是程序員。 – Neil 2012-04-26 14:12:59

+0

這真的取決於您的應用程序。如果您擁有數據庫的控制權,那麼添加一個約束就可以很好地封裝您的規則。但是,如果您的交易量很大,並且您希望大部分記錄已經存在,那麼在SQL中處理它會更有效率。 – Greg 2012-04-26 14:19:53

+1

的確如此,但問題是這個問題不會發生,應該被視爲例外,而不是規則。因此,無論是程序員捕獲約束異常還是更好,他都會自己避免多次調用,並且您可以獲得效率和正確性。 – Neil 2012-04-26 14:28:37

1

你可以這樣做:

INSERT INTO SERVICEPAYANT_CLIENT (RE_ID, TYPE_DONNEES) 
SELECT CLIENT_ID, 160 AS TYPE_DONNEES 
REFERENTIEL r 
JOIN CLIENT_APPLICATIF ca 
    ON r.ID = ca.ID_REFERENTIEL 
WHERE 
    r.TYPE=1 
    AND NOT EXISTS 
     (
      SELECT 
       NULL 
      FROM 
       SERVICEPAYANT_CLIENT 
      WHERE 
       REFERENTIEL.CLIENT_ID=SERVICEPAYANT_CLIENT.RE_ID 
     ) 
GROUP BY CLIENT_ID 
HAVING COUNT(*)>0; 
1

有在這些情況下,一些成熟的DBMS一句MERGEMERGEINSERTUPDATE在同一時間。

一般語法示例:

 MERGE INTO TABLE_NAME USING table_reference ON (condition) 
     WHEN MATCHED THEN 
     UPDATE SET column1 = value1 [, column2 = value2 ...] 
     WHEN NOT MATCHED THEN 
     INSERT (column1 [, column2 ...]) VALUES (value1 [, value2 ... 

某些DBMS像MySQL有自己的語法有同樣的想法。 查看更多的Wikipedia

如果您的DBMS沒有soppurt,那麼您可以使用相同的邏輯編寫一個存儲過程。

但是,在插入代碼之前,存儲過程或任何其他類型的其他檢查都會導致「滯後」,並且操作將變爲「非原子」。這意味着可能在檢查之後和插入之前,另一個事務可以創建重複記錄,並且會得到意外的重複或異常。爲了避免這種情況,您必須在執行此操作之前鎖定表格,以便獲得對錶格的獨佔訪問權限,因爲訪問的序列化會導致懲罰性損失。

或者你可以使用INSERTSELECT這樣的:

INSERT (field1, ...) INTO table1 
    SELECT value1, ... 
    FROM DUAL -- put a name of analogue of Oracle's DUAL here 
    WHERE NOT EXISTS (
     SELECT 1 
     FROM table1 
     WHERE key = :new_key 
    ) 

但你知道它不會更新任何內容。