Sql-Server
SQL插入具有唯一約束的多個值
我有一個 MS SQL Server 2012 和下表:
CREATE TABLE dzp.contractid ( id bigint PRIMARY KEY IDENTITY(1,1), VNR char(18) NOT NULL, CONSTRAINT UC_VNR UNIQUE (VNR))
對於上下文,VNR 表示字元串形式的唯一契約編號。
我想導入包含契約資訊的 csv 文件,每個契約可能包含多行。為了避免對 char(18) 進行查詢,我試圖在使用暫存表的 INSERT-Trigger 載入時對數據進行規範化。
流程是:
csv-file --> staging table --> insert trigger --> normalized tables
在我的觸發器中,我正在嘗試以下操作:
BEGIN TRY INSERT INTO dzp.contractid(VNR) SELECT VNR FROM dzp.accounts_stage END TRY BEGIN CATCH -- ignore unique constraint violation error, raise otherwise IF ERROR_NUMBER() <> 2627 RAISERROR ('blah', 16, 1) END CATCH
所以我希望實現的基本上是:
- 從臨時表中獲取所有契約號
- 將所有這些數字添加到規範化表中
- 忽略違反唯一約束時引發的錯誤
- 正常工作時,我現在有一個包含所有唯一 VNR 的表
問題:
Uniqueness-Constraint 似乎阻止了整個 INSERT,而不僅僅是實際重複的值。
是否有某種方法可以逐行插入數據,或者告訴約束逐行處理它?
這甚至是正確的方法嗎?我很高興完全改變這種方法,因為我無法想像我是第一個遇到這個問題的人……就上下文而言,這本質上是一個報告數據庫,每天批處理一次,總共大約 100 萬行(來自 csv 表),並且有大約 5 個使用者不時執行查詢。
感謝您的輸入!
SQL 約束違反影響整個語句,您不能忽略個別行。
您可以做的是僅插入不違反約束的行。有幾種方法可以做到這一點,例如
INSERT INTO dzp.contractid(vnr) SELECT DISTINCT vnr FROM dzp.accounts_stage s WHERE NOT EXISTS (SELECT 1 FROM dzp.contractid WHERE vnr = s.vnr)
你也可以使用
MERGE
:MERGE dzp.contractid AS t USING dzp.accounts_stage AS s ON (t.vnr = s.vnr) WHEN NOT MATCHED BY TARGET THEN INSERT(vnr) VALUES(s.vnr)