从固定宽度的平面文件到SQL 2000中获取数百万条记录

时间:2020-03-06 14:30:03  来源:igfitidea点击:

显然我可以使用BCP,但这是问题所在。如果批处理中的某条记录的日期无效,我想将其重定向到单独的表/文件/任何地方,但要保持批处理的运行。我认为SSIS不能安装在服务器上会有所帮助。

解决方案

创建一个在INSERT上处理的触发器。此触发器将对日期字段进行验证检查。如果验证失败,则在单独的表中进行插入,我们也可以选择继续插入还是不允许插入。

重要说明:默认情况下,触发器不会在批量插入内容上触发(包括BCP和SSIS)。为了使它起作用,我们需要使用以下方法指定要触发的触发器:

BULK INSERT your_database.your_schema.your_table FROM your_file WITH (FIRE_TRIGGERS )

我们是说文件中有一列充满日期的列,并且我们希望该数据进入SQL数据库的表中" datetime"类型的列中?如果文件中的值之一不是有效日期,它会爆炸吗?我只是想确保我理解这一权利。

我们可以在SQL数据库中创建另一个临时表,该表的结构与我们希望文件中的数据结尾的表的结构相同,但每一列的类型均为varchar(255)或者类似内容。无论日期是否有效,将数据从文件中吸到表中都不会失败。

然后,在SQL中,我们可以随意调整数据。我们可以使用游标从临时表中选择所有记录,然后遍历它们。对于每条记录,可以使用T-SQL ISDATE函数有条件地将当前记录中的值插入一个表或者另一个表中。

我的意思是,将数据放入数据库,然后像这样运行脚本:

// **this is untested, there could be syntax errors**

// if we have tables like this:
CREATE TABLE tempoary (id VARCHAR(255), theDate VARCHAR(255), somethingElse VARCHAR(255))
CREATE TABLE theGood  (id INT, theDate DATETIME, somethingElse VARCHAR(255))
CREATE TABLE theBad   (id INT, theDate VARCHAR(255))

// then after getting the data into [tempoary], do this:
DECLARE tempCursor CURSOR
FOR SELECT id, theDate, somethingElse FROM temporary

OPEN tempCursor

DECLARE @id VARCHAR(255)
DECLARE @theDate VARCHAR(255)
DECLARE @somethingElse VARCHAR(255)

FETCH NEXT FROM tempCursor INTO @id, @theDate, @somethingElse
While (@@FETCH_STATUS <> -1)
BEGIN
    IF ISDATE(@theDate)
    BEGIN
        INSERT INTO theGood (id, theDate, somethingElse)
        VALUES (CONVERT(INT, @id), CONVERT(DATETIME, theDate), somethingElse)
    END
    ELSE
    BEGIN
        INSERT INTO theBad (id, theDate)
        VALUES (CONVERT(INT, @id), theDate)
    END
    FETCH NEXT FROM tempCursor INTO @id, @theDate, @somethingElse
END
CLOSE tempCursor
DEALLOCATE tempCursor

是的,如果我们使用的是DTS,则应仅导入使用varchar而不是日期的登台表,然后将数据整理到适当的表后缀中。

Matt所说的问题是,以后不应该使用游标来操纵数据,尤其是当我们有数百万条记录时。 CURROPRS效率极低,应避免使用。

请改用批处理。

但是,请务必使用他关于登台表的想法。我永远不会考虑直接导入到生产表中,因为随着时间的流逝会发生太多事情,从而更改输入文件中的数据并引起问题。