继续在表中插入数据,跳过重复数据问题

时间:2016-02-07 20:32:47

标签: sql-server sql-server-2008 tsql

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查询而不管重复数据?我不想改变索引或表格。

1 个答案:

答案 0 :(得分:1)

  

当任何重复数据出现时,我无法继续插入数据。有没有其他方法可以继续运行SQL查询而不管重复数据。我不想改变索引或表格。

您可以做的是在调用它们时更改插入脚本,在此伪声明中:

select @SQL=some select query to fetch insert scripts
  
      
  1. 更改生成脚本:生成INSERT INTO ... VALUES(...)语句
  2. ,而不是生成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);
  
      
  1. 更改生成脚本:生成INSERT INTO ... SELECT ...语句
  2. ,而不是生成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);
  
      
  1. @SQL中的目标表名替换为临时表(所谓的临时表),然后使用WHERE NOT EXISTS(...)
  2. 从临时表插入目标表   

这样您就不必更改插入生成脚本。首先创建一个临时表,其结构与目标表完全相同(不包括主键)。然后使用临时表的名称替换@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;