SQL Server:找出导致TSQL失败的行(SSIS)

时间:2009-07-07 19:56:06

标签: sql-server sql-server-2005 tsql ssis

SQL Server 2005问题:

我正在进行一个数据转换项目,我正在使用80k +行并将它们从一个表移动到另一个表。当我运行TSQL时,它会因为转换类型或其他任何错误而遭受各种错误的轰炸。有没有办法找出导致错误的行?

=====================

更新:

我正在执行INSERT INTO TABLE1(...)SELECT ... FROM TABLE2 Table2只是一堆varchar字段,其中TABLE1具有正确的类型。

此脚本将放入sproc并从SSIS包执行。 SSIS包首先将5个大型平面文件导入TABLE2。

以下是一条示例错误消息:“将char数据类型转换为日期时间数据类型会导致超出范围的datetime值。”

有许多日期字段。在TABLE2中,有一些数据值,例如Birthdate的'02 / 05/1075'。我想检查导致错误的每一行,因此我可以向负责坏数据的部门报告,以便他们可以纠正错误。

7 个答案:

答案 0 :(得分:5)

这不是使用SSIS的方法。您应该拥有从源到目的地的数据流,以及中间需要的任何转换。您将能够通过使用目标的错误输出来获取错误详细信息,实际上是错误行。

我经常将目的地的错误输出发送到另一个目的地 - 文本文件或设置为允许所有内容的表格,包括在真实目的地中无效的数据。


实际上,如果以SSIS中的标准方式执行此操作,则应在设计时检测数据类型不匹配。

答案 1 :(得分:3)

我所做的是使用WHERE子句将行集分成两半:

INSERT MyTable(id, datecol) SELECT id, datecol FROM OtherTable WHERE ID BETWEEN 0 AND 40,000

然后继续更改where子句之间的值。我已经手动完成了很多次,但是我发现你可以在一个循环中使用一些.Net代码自动分割,捕获异常,然后将它缩小到抛出异常的行,一点一点。

答案 2 :(得分:2)

我假设您使用INSERT INTO进行更新...

而是尝试使用游标进行更新,使用异常处理来捕获错误并记录所需的全部内容:失败的行号等。

答案 3 :(得分:2)

不完全是游标,但是有效 - 我有超过400万行要检查多个转换失败。这是我使用的,它导致了两个临时表,其中包含我的所有值和分配的行,还有一个只包含第一个临时表中无法转换的行列表。

select row_number() over (order by TimeID) as rownum,timeID into #TestingTable from MyTableWithBadData

set nocount on
declare @row as int
declare @last as int
set @row=0
select @last = count(*) from #TestingTable
declare @timeid as decimal(24,0)
create table #fails (rownum int)
while @row<=@last
begin
    Begin Try
        select @timeid=cast(timeID as decimal(24,0)) from #TestingTable where rownum = @row 
    end try
    begin catch 
        print cast(@row as varchar(25)) + ' : failed'
        insert into #fails(rownum) values(@row)
    end catch
    set @row = @row+1
end

答案 4 :(得分:1)

如果要循环,请在循环中添加打印件。

如果您使用基于集合的操作,请添加限制性WHERE条件并运行它。继续运行它(每次都使它越来越严格),直到你可以找到数据中的行。如果你可以为N行的块运行它,那么只需选择那些行并查看它们。

添加CASE语句以捕获问题(将该错误值转换为NULL或更改)并在新的FlagColumn中添加一个值,告诉您问题的类型:

CASE WHEN ISNUMERIC(x)!=1 then NULL ELSE x END as x
,CASE WHEN ISNUMERIC(x)!=1 then 'not numeric' else NULL END AS FlagColumn

然后选择新转换的数据,其中FlagColumn IS NOT NULL

您可以尝试在源数据的各个列上使用带有isnumeric()或isdate()函数的select语句

编辑

  

有许多日期字段。在TABLE2中,   有数据值,如   '02 / 05/1075'为Birthdate。我想要   检查导致该行的每一行   错误,所以我可以报告   负责坏的部门   数据,以便他们可以纠正它。

使用此命令返回所有错误日期行:

SELECT * FROM YourTable WHERE ISDATE(YourDateColumn)!=1

答案 5 :(得分:0)

如果你正在使用游标,是的并且是微不足道的。如果您不使用游标,我不这么认为,因为SQL操作是ACID或本身的事务。

答案 6 :(得分:0)

John Sauders有正确的想法,有更好的方法使用SSIS进行这种处理。但是,学习SSIS并重新打包以彻底改变过程可能不是一个选项,所以我提供这个建议。您似乎遇到日期不正确的问题。因此,首先运行查询以识别那些错误的记录并将它们插入到execptions表中。那么你只插入剩下的那些记录。类似的东西:

 insert exceptiontable (field1, field2)
 select field1, field2 from table2 where isdate(field2) = 0

 insert table1 (field1, field2)
 select field1, field2 from table2 where isdate(field2) = 1

当然,您可以将异常表的内容发送给提供错误数据的人员。