BULK INSERT缺失最后一行?

4

我使用BULK INSERT来处理我的文本文件。一切都很顺利,但我发现了一个问题,如果我在最后一行的最后一列给出一个值,那么它会被导入。但是,如果最后一行的最后一列的值为空白,它会丢弃该行,尽管目标列允许空值!文本文件使用制表符分隔符,下面是最后一行数据的示例:

Mike    Johnson 1/29/1987   M

如果在最后一列字段中有任何值,将插入行,例如:
Mike    Johnson 1/29/1987   M   test

这是我的批量插入操作:
BULK INSERT ##TEMP_TEXT
FROM '#uncdir#\#cffile.ServerFile#'
WITH (
    FIELDTERMINATOR = '\t', 
    ROWTERMINATOR = '\n'
)

我尝试使用 \r 而不是 \n,但这并没有解决问题。我也在一些网站上进行了研究,但没有找到任何解决方案。我想知道是否可以在 SQL 中修复此问题。如果有人知道如何解决,请告诉我。
解决方案: 对于任何使用 ColdFusion 的人,下面是添加文本文件中换行符的行:
exec xp_cmdshell 'echo. >> "#uncdir#\#cffile.ServerFile#"';

关键在于将 coldfusion 变量用双引号括起来,否则代码无法正常工作。

uncdir 代码如下:

<cfset uncdir = createObject("java","java.net.InetAddress").getLocalHost().getHostName()/>

cffile.ServerFile是可以从表单获取的。我使用了JQuery来提交文本文件。希望这能帮到你。谢谢。


你试过使用\r\n吗? - TT.
我尝试了,但是这导致了错误:coldfusion.tagext.sql.QueryTag$DatabaseQueryException: Error Executing Database Query。 - espresso_coffee
最后一个字段没有制表符来结束这行吗?因为我认为即使对于 NULL 值,最后一个分隔符也需要存在。 - TT.
为了排除可能的错误,您是否安装了最新的SP - TT.
这是唯一的解决方案吗?另外,如果我需要添加一个换行符,我可以在SQL中做到这一点,还是必须在BULK INSERT之前完成? - espresso_coffee
显示剩余6条评论
1个回答

8

我在 SQL Server 2008 R2 上重现了你的问题。解决方案就是在你的文件末尾添加一个换行符。

我创建了两个文件:

  1. without_newline
  2. with_newline
然后运行以下脚本:
CREATE TABLE #t(first_name VARCHAR(128),last_name_etc VARCHAR(128),sex CHAR(1),test VARCHAR(128));

BULK INSERT #t
FROM 'C:\temp\without_newline.txt'
WITH (
    FIELDTERMINATOR='\t',
    ROWTERMINATOR='\n'
);

SELECT * FROM #t;

TRUNCATE TABLE #t;

BULK INSERT #t
FROM 'C:\temp\with_newline.txt'
WITH (
    FIELDTERMINATOR='\t',
    ROWTERMINATOR='\n'
);

SELECT * FROM #t;

DROP TABLE #t;

结果 1:

first_name  | last_name_etc     | sex | test
--------------------------------------------
Tom         | Jackson 2/28/1986 | M   | test

结果 2:

first_name  | last_name_etc     | sex | test
--------------------------------------------
Tom         | Jackson 2/28/1986 | M   | test
Mike        | Johnson 1/29/1987 | M   | NULL

解决方案应该很简单,只需确保最后一行以\r\n结束。你可以更改生成文本文件的进程或在批量插入之前手动执行此操作。
手动执行此操作的一种方法是在批量插入之前运行EXEC xp_cmdshell 'echo. >> C:\temp\without_newline.txt'

我终于让它工作了,添加新行就解决了问题。在我处理这段代码时,有一件事情浮现在我的脑海中。命令cmdshell正在向文件中添加新行,如果文件不在我的电脑上,我将如何能够检测到文件的根目录/文件夹呢?假设其他用户想要上传他/她的文件,并且该文件位于他们的计算机上。在这种情况下,我使用的目录将是不同的,这将导致问题。 - espresso_coffee
嗨@espresso_coffee。我不确定我是否完全明白您的意思。在批量插入命令中,data_file没有涉及“检测”。根据文档所述:“data_file必须指定SQL Server正在运行的服务器上的有效路径。如果data_file是远程文件,请指定UNC(通用命名约定)名称。”不过,SQL Server帐户可能没有写访问权限。在这种情况下,您无法做太多事情。也许将文件复制到具有写访问权限的帐户? - TT.
@espresso_coffee 不过,最好的方法可能是让生成数据文件的进程在末尾加上一个换行符。 - TT.
1
我终于让它工作了。问题出在我在xp_cmdshell命令中输出的coldfusion变量周围的双引号上。现在我正在为每个已上传的文件添加换行符。感谢您的所有帮助。我认为这是解决此问题的唯一方法。我在网上找不到其他可以修复此错误的东西。 - espresso_coffee
1
如果有人上传他们的文件,副本将使用应该对您或同事可用的代码发送到您的服务器。该代码可以将文件放置在您想要的任何位置。 - Dan Bracuk
由于文件已上传到CF服务器,因此它也可以通过CF代码进行操作。 - Leigh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接