找出导致错误的行

时间:2010-05-11 13:45:55

标签: sql-server sql-server-2005 tsql integration-testing

我有一个很大的胖查询,它是动态编写的,用于集成一些数据。基本上它的作用是查询一些表,加入其他表,处理一些数据,然后将其插入到最终表中。

问题在于数据太多,我们无法真正信任这些数据源,因为可能存在一些错误或不一致的数据。

例如,我在使用客户数据库开发时花了将近一个小时寻找错误,因为在我的大胖查询中间某处将一些varchar转换为datetime时出错。事实证明,他们有一些销售约会'2009-02-29',这是一个超出范围的日期。 是的,我知道。为什么存储为varchar?那么,源数据库有3列日期,'月','日'和'年'。我不知道为什么会这样,但它仍然是。

但是,如果来源不可信,我该怎么处理呢?

我无法处理异常,我真的需要它与原始消息达到另一个级别,但我想提供更多信息,以便用户在致电我们之前至少可以尝试解决它。 / p>

所以我考虑向用户显示行号,或者一些ID,至少可以让他知道他必须纠正的记录。这也是一项艰苦的工作,因为有时集成将达到80000条记录。 在80000记录集成中,单个虚拟错误消息:'将varchar数据类型转换为日期时间数据类型导致超出范围的日期时间值'表示什么都没有。< / p>

所以任何想法都会受到赞赏。

哦,我正在使用带有Service Pack 3的SQL Server 2005。


修改

好的,所以对于我所读到的答案,最好的办法是检查每一列可能对提出错误至关重要,如果他们确实参加了这个条件,我应该自己提出错误,并留言我找到更具描述性的内容,并添加一些可能存储在单独的表或某些变量中的信息,例如行的ID或其他一些根信息。

4 个答案:

答案 0 :(得分:2)

您可以使用isdate函数的日期

select ISDATE('20090229'),ISDATE('20090227')

我通常会插入临时表,执行检查,然后插入真实表格

答案 1 :(得分:2)

我的建议是预先验证传入的数据,当您遇到错误时,请留出记录。例如,检查无效日期。假设您在一组80K中找到20个。将这20个拉出到一个单独的表中,并将错误消息附加到记录中。运行您的其他验证,然后最终将剩余的(所有有效)记录导入到所需的目标表中。

这可能会对性能产生太大影响,但可以让您轻松指出错误并允许更正错误,然后再插入第二次传递。

答案 2 :(得分:1)

尝试这样的方法来查找行:

...big fat query here...
WHERE ISDATE(YourBadVarcharColumn)!=1

将数据加载到临时表中,其中大多数列都是varchar并允许NULL,其中有一个状态列。

运行像

这样的UPDATE命令
UPDATE Staging
    SET Status='X'
    WHERE ISDATE(CONVERT(YourCharYear+YourCharMonth+YourCharDat+)!=1 
        OR OtherColumn<4...

然后只需从您的临时表中插入Status!='X'

INSERT INTO RealTable
        (col1, col2...)
    SELECT
        col1, col2, ...
        where Status!='X'

答案 3 :(得分:1)

这听起来像标准的ETL问题:提取,转换和加载。 (除非你必须一遍又一遍地对同一组数据运行这个查询,在这种情况下,你几乎一遍又一遍地做同样的事情。那么性能有多重要?)

您可以提供哪种错误处理和/或“错误数据报告”?如果您将所有内容都视为“一个大胖查询”,您的选项将变得非常有限 - 无论是查询是否有效,如果不是,我猜你最多只能获得一条RAISERROR消息来告诉来电者什么是。

在这种情况下,我尝试设置的一般框架是:

  • 从源表开始
  • 生成一组临时表(SQLMenace的临时表),您知道是一致的并且形式正确(有效数据,密钥等)
  • 针对这些表格写下“不太大而且很胖的查询”

通过这种方式,您应该始终能够返回(或存储)有效数据集...即使它是空的。诀窍在于确定例程何时失败 - 数据何时过于腐败而无法处理并产生所需的结果,因此您返回一个措辞恰当的错误消息呢?