代码之家  ›  专栏  ›  技术社区  ›  Jon Erickson

SQL 2000“Try Catch Like”错误处理

  •  5
  • Jon Erickson  · 技术社区  · 16 年前

    这是我正在使用的SQL 2000数据库。

    我有一个我称之为临时表的表,它是数据的原始数据转储,所以一切都是ntext或nvarchar(255)。

    我需要将所有这些数据转换成适当的数据类型(例如int、decimal、nvarchar等)。

    我这样做的方法是使用while循环遍历所有记录,并在每次迭代期间尝试对单个记录的每个列进行强制转换,在访问特定记录后,我将其标记为已处理(位字段)。

    但是,如果发生错误,我如何记录它,但是允许while循环继续。

    起初,我使用本地SQL 2005实例中的一个Try-Catch实现了这一点(以使项目顺利进行),但现在我了解到,国际DBA设置的开发和生产数据库是一个SQL 2000实例,因此我必须遵守。

    编辑 :我正在使用ssis包填充临时表。我看到了,现在我必须重新访问该包并实现一个脚本组件来处理转换。谢谢大家

    编辑 在逐记录的基础上执行此操作,而不是批量插入,因此事务处理的想法似乎是可行的,但我不确定如何捕获@@error并允许存储过程继续。

    编辑 我真的很喜欢 Guy's approach ,我将以这种方式实现它。

    5 回复  |  直到 15 年前
        1
  •  2
  •   Guy    16 年前

    一般来说,我不喜欢“循环通过记录”解决方案,因为它们往往速度很慢,最终会编写很多自定义代码。

    所以…

    根据临时表中的记录数,可以使用一系列SQL语句对数据进行后期处理,这些语句测试列的正确性,并标记任何未通过测试的记录。

    UPDATE staging_table
    SET status_code = 'FAIL_TEST_1'
    WHERE status_code IS NULL
    AND ISDATE(ntext_column1) = 0;
    
    UPDATE staging_table
    SET status_code = 'FAIL_TEST_2'
    WHERE status_code IS NULL
    AND ISNUMERIC(ntext_column2) = 0;
    
    etc...
    

    终于

    INSERT INTO results_table ( mydate, myprice )
    SELECT ntext_column1 AS mydate, ntext_column2 AS myprice
    FROM staging_table
    WHERE status_code IS NULL;
    
    DELETE FROM staging_table
    WHERE status_code IS NULL;
    

    临时表包含所有错误,您可以导出并报告这些错误。

        2
  •  2
  •   jason saldo    16 年前

    你用什么导入文件?DTS具有可用于数据验证的脚本功能。如果不使用DTS,您是否使用自定义工具?如果是这样,请在那里进行验证。

    但我想这就是你要找的。
    http://www.sqlteam.com/article/using-dts-to-automate-a-data-import-process

    IF @@Error <> 0
     GOTO LABEL
    

    @ OP
    在SSIS中,数据导入任务的“红线”可以将坏行重定向到单独的目标或转换。我有一段时间没玩过了,但希望能有所帮助。

        3
  •  1
  •   FlySwat    16 年前

    在事务中运行每个强制转换,每次强制转换后,检查@@error,如果清除,则提交并继续。

        4
  •  1
  •   Blorgbeard    16 年前

    看来你命中注定了。见 this 文件。

    tl/dr:数据转换错误总是导致整个批处理中止-无论您做什么,您的SQL脚本都不会继续执行。交易不会有帮助。您不能检查@@error,因为执行已经中止。

    我首先要重新检查一下为什么需要一个充满varchar(255)列的临时数据库——填充该数据库的内容可以进行转换吗?

    如果没有,我想您需要编写一个程序/脚本来从varchar列中进行选择、转换并插入到prod db中。

        5
  •  1
  •   kristof    16 年前

    您可以尝试在强制转换之前检查数据类型,并实际避免引发错误。

    您可以使用如下函数:

    ISNUM - to check if the data is of a numeric type
    ISDATE - to check if it can be cast to DATETIME