set xact_abort off;
begin tran
DECLARE @error int
declare @SQL nvarchar(max)
set @SQL=N'';
select @SQL=some select query to fetch insert scripts
begin try
exec sp_executesql @SQL
commit
end try
begin catch
select @error=@@Error
if @error=2627
begin
continue inserting data
end
if @error<>2627
begin
rollback
end
end catch
当任何重复数据出现时,我无法继续插入数据。有没有其他方法可以继续运行SQL查询而不管重复数据?我不想改变索引或表格。
答案 0 :(得分:1)
当任何重复数据出现时,我无法继续插入数据。有没有其他方法可以继续运行SQL查询而不管重复数据。我不想改变索引或表格。
您可以做的是在调用它们时更改插入脚本,在此伪声明中:
select @SQL=some select query to fetch insert scripts
- 更改生成脚本:生成
,而不是生成INSERT INTO ... VALUES(...)
语句IF NOT EXISTS(...) INSERT INTO ... VALUES(...)
语句 醇>
这些插入语句应首先检查表中是否已存在密钥。如果您的插入语句的格式为
INSERT INTO some_table(keycol1,...,keycolN,datacol1,...,datacolM)VALUES(keyval1,...,keyvalN,dataval1,...,datavalM);
您可以将其重写为:
IF NOT EXISTS(SELECT 1 FROM some_table WHERE keycol1=keyval1 AND ... AND keycolN=keyvalN)
INSERT INTO some_table(keycol1,...,keycolN,datacol1,...,datacolM)VALUES(keyval1,...,keyvalN,dataval1,...,datavalM);
- 更改生成脚本:生成
,而不是生成INSERT INTO ... SELECT ...
语句INSERT INTO ... SELECT ... WHERE NOT EXISTS(...)
醇>
如果表中尚不存在该键,则可以将这些语句更改为仅插入。假设您的insert语句的格式为:
INSERT INTO some_table(keycol1,...,keycolN,datacol1,...,datacolN)
SELECT _keycol1,...,_keycolN,datacol1,...,datacolN
FROM <from_clause>;
您可以将其重写为:
INSERT INTO some_table(keycol1,...,keycolN,datacol1,...,datacolN)
SELECT _keycol1,...,_keycolN,datacol1,...,datacolN
FROM <from_clause>
WHERE NOT EXISTS(SELECT 1 FROM some_table WHERE keycol1=_keycol1 AND ... AND keycolN=_keycolN);
- 将
从临时表插入目标表 醇>@SQL
中的目标表名替换为临时表(所谓的临时表),然后使用WHERE NOT EXISTS(...)
这样您就不必更改插入生成脚本。首先创建一个临时表,其结构与目标表完全相同(不包括主键)。然后使用临时表的名称替换@SQL
中目标表名称的所有实例。运行@SQL
,然后使用WHERE NOT EXISTS(...)
从临时表插入目标表。
假设目标表的名称为some_table
,关键列为key_col1,...,key_colN
,数据列为datacol1, ..., datacolM
。
SELECT * INTO #staging_table FROM some_table WHERE 1=0; -- create staging table with same columns as some_table
SET @SQL=REPLACE(@SQL,'some_table','#staging_table');
EXEC sp_executesql @SQL;
INSERT INTO some_table(keycol1,...,keycolN,datacol1,...,datacolN)
SELECT st.keycol1,...,st.keycolN,st.datacol1,...,st.datacolN
FROM #staging_table AS st
WHERE NOT EXISTS(SELECT 1 FROM some_table WHERE keycol1=st.keycol1 AND ... AND keycolN=st.keycolN);
DROP TABLE #staging_table;