显然我可以使用BCP,但这是问题所在。如果批处理中的某个记录具有无效日期,我想将其重定向到单独的表/文件/其他,但保持批处理正在运行。我不认为SSIS可以安装在服务器上,这本来有帮助。
答案 0 :(得分:5)
创建一个在INSERT上处理的触发器。此触发器将对您的日期字段进行验证检查。如果验证失败,则插入单独的表中,您也可以选择继续插入或不允许它通过。
重要注意:默认情况下,触发器不会触发批量插入(包括BCP和SSIS)。要使其正常工作,您需要使用以下内容指定触发器:
BULK INSERT your_database.your_schema.your_table FROM your_file WITH (FIRE_TRIGGERS )
答案 1 :(得分:3)
是的,如果你正在使用DTS,你应该只导入一个使用varchar而不是日期的临时表,然后按照数据将数据按到正确的表格中。
答案 2 :(得分:3)
Matt所说的问题是你不应该使用游标来操纵数据,特别是如果你有数百万条记录。 CUrsoprs效率极低,应该避免使用。
改为使用批处理。
但是一定要使用他的临时表的想法。我不会考虑直接导入到生产表中,因为随着时间的推移会发生太多事情来更改输入文件中的数据并导致问题。
答案 3 :(得分:0)
你说文件中有一个满了日期的列,你希望这些数据进入SQL数据库表中的“datetime”类型的列吗?如果文件中的某个值不是有效日期,它会爆炸吗?我只是想确保我理解这一点。
您可以在SQL数据库中创建另一个临时表,其结构与您希望文件中的数据结束的表相同,但每个列的类型为varchar(255)或其他类。无论任何日期是否有效,将数据从文件中吸出并进入该表都不会失败。
然后,在SQL中,您可以根据需要按摩数据。您可以使用cursor从临时表中选择所有记录并循环遍历它们。对于每条记录,您可以使用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