2016-02-11 213 views
1

我正在写使用语句INSERT INTO SELECT错误处理

INSERT INTO [tableName] 
..... 
SELECT * FROM [tableName] 

有时输入表(SELECT)的存储过程插入到表中的T-SQL可能包含错误值:表,其中插入是期望一个小数,并且select返回一个NVarChar值,这将引发转换错误。 现在因为语句执行了“批量插入”,我不知道插入的最后一条记录是什么或者包含错误数据的记录是什么。 SQL只说“转换错误.....” 有什么办法可以“记录”最后插入的记录,以便至少我知道哪一行包含错误的值? (不使用游标)

+0

你可以运行一个while循环,遍历的ID,并通过一个由ID一个插入,每个插入之前打印的ID,所以你知道哪一个失败 – artm

+0

什么是您的源? – sagi

+0

如果批量失败,没有记录被插入.. –

回答

2

没有最后一个错误。

根据基本的数据库ACID条件,该语句是ATOMIC - 它完全工作或完全失败。还没有内部处理行的定义顺序 - 这可能会因服务器和数据特征而异。

通常,在将数据复制到目标表之前会清理数据。

1

您可以尝试使用OUTPUT子句,以便输出插入的行直到遇到错误。您也可以使用ORDER BY,以便更快地确定哪个插入失败的下一行。然后,知道失败的行,应该更容易确定问题的领域。有一个OUTPUT子句

MSDN Link

的UPDATE,INSERT或DELETE语句将 回行即使语句遇到错误, 回滚客户端。如果在运行语句时发生任何错误,则不应使用 。

5

观察这个查询的结果

SELECT 
    v.id, 
    v.val, 
    x=TRY_CAST(v.val AS DECIMAL(28,2)) 
FROM 
    (VALUES(1,'1.26'),(2,'A.13')) AS v(id,val) 
WHERE 
    TRY_CAST(v.val AS DECIMAL(28,2)) IS NULL 

结果:

+----+------+------+ 
| id | val | x | 
+----+------+------+ 
| 2 | A.13 | NULL | 
+----+------+------+ 

它采用TRY_CAST,返回NULL如果CAST失败。您可以使用它来确定失败的记录,或者缩小您插入到目标表中的集合。

+0

好的技巧和尝试的用法cast – TheGameiswar

1

您可以使用以下语句指出哪个列正在进行转换问题。

SELECT SQL_VARIANT_PROPERTY(col1, 'BaseType') from Table1 

要过滤的问题

SELECT * from Table1 WHERE QL_VARIANT_PROPERTY(col1, 'BaseType') not like 'decimal%' 
+0

如果源列的类型是'NVARCHAR', 'SQL_VARIANT_PROPERTY(col,'BaseType')'只会返回'NVARCHAR'。这对OP没有帮助。 –

+0

感谢您的信息:) –

1

我曾经面临过这样的问题,在一台进口15万行。我们最终决定它最好在SSIS中完成与以下方法:

  1. 创建可以说带有一个后续其他“ON ERROR”只有
  2. 在第一数据任务设置n个数据的任务提交的批处理为100K。并在错误转到下一个我们命名为10K
  3. 在这个任务,是10K,我们设置COMMIT批量为10K和“ON错误”我们去1K等等等等。
  4. 我们最终在COMMIT BATCH数据任务“ON ERROR”的1条记录中,将数据移动到一个具有足够列(所有VARCHAR/NVARCHAR)的表中(调用ERROR RECORD表),以保存传入数据+一个额外列为该行保存SSIS错误消息。

当SSIS结束后,我们会分析所有失败的记录。通过这种方式,可以说你在1500万个中只有5个错误记录,我们可以在隔离表中成功插入1499995个记录和5个记录。

感谢,并希望这种方法能帮助