从固定宽度的平面文件到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效率极低,应避免使用。
请改用批处理。
但是,请务必使用他关于登台表的想法。我永远不会考虑直接导入到生产表中,因为随着时间的流逝会发生太多事情,从而更改输入文件中的数据并引起问题。