zui*_*iqo 3 sql-server constraint insert sql-server-2012 unique-constraint
我有一个 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))
Run Code Online (Sandbox Code Playgroud)
对于上下文,VNR 表示字符串形式的唯一合同编号。
我想导入一个包含合同信息的 csv 文件,每个合同可能有多行。为了避免查询 char(18),我尝试在加载时使用临时表的 INSERT-Trigger 规范化数据。
流程是:
csv-file --> staging table --> insert trigger --> normalized tables
Run Code Online (Sandbox Code Playgroud)
在我的触发器中,我正在尝试以下操作:
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
Run Code Online (Sandbox Code Playgroud)
所以我希望实现的基本上是:
问题:
Uniqueness-Constraint 似乎阻止了整个 INSERT,而不仅仅是实际重复的值。
是否有某种方法可以逐行插入数据,或者告诉约束逐行处理它?
这甚至是正确的方法吗?我很高兴完全改变方法,因为我无法想象我是第一个遇到这个问题的人......对于上下文,这本质上是一个每天批量输入一次的报告数据库,总共有大约 100 万行(来自 csv-table),并且有大约 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)
Run Code Online (Sandbox Code Playgroud)
您还可以使用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)
Run Code Online (Sandbox Code Playgroud)