尝试将.tsv文件批量插入sql-server-linux docker镜像时,你有没有得到这个错误:
Referenced external data source "(null)" not found.
这是命令,表存在,文件存在于服务器上:
BULK INSERT countries FROM '/import/file.tsv'
WITH (
FIELDTERMINATOR = '\t'
);
谢谢托马斯
这是Linux上的SQL Server中的错误,我们处理路径的方式。我们仍在努力使SQL Server中的所有内容都能处理Linux路径语法。我已经提交了一个错误,我们会修复它。在此期间,您可以将路径指定为C:\ import \ file.tsv,其中C:\是Linux文件系统根目录的占位符(即'/'),斜杠只是反转。我在RHEL VM中测试了这个确切的场景,它运行正常。专业提示:这个C:\技巧将适用于在T-SQL中传递路径的任何地方,因此如果您遇到其他需要路径的问题,请尝试一下。
Bug#9380471 for Microsoft-internal reference。
我在Ubuntu 18上运行了一个MSSQL,并通过将我的CSV文件移动到Ubuntu(/)的根目录来解决同样的问题。它终于看到了CSV文件并且工作正常。
BULK INSERT Students FROM '/student.csv' WITH ( FORMAT='CSV');
我在Linux上遇到了很多麻烦,其中一个有效的路径名被拒绝:
# sqlcmd -S localhost -d leak -U sa -Q "BULK INSERT leak FROM '/tmp/data.txt'"
Msg 12703, Level 16, State 1, Server mssql, Line 1
Referenced external data source "(null)" not found.
# ll /tmp/data.txt
-rw-r--r-- 1 root root 30M Feb 20 02:40 /tmp/data.txt
并建议使用反斜杠替换斜杠并预先添加C:\的解决方法不起作用:
# sqlcmd -S localhost -d leak -U sa -Q "BULK INSERT leak FROM 'C:\\tmp\\data.txt'"
Msg 12703, Level 16, State 1, Server mssql, Line 1
Referenced external data source "(null)" not found.
所以,我调查了一下,通过在守护进程上运行strace,我发现了这个:
# strace -fp 3198 -e open
strace: Process 3198 attached with 175 threads
[pid 3202] open("/proc/self/status", O_RDONLY) = 170
[pid 3202] open("/proc/meminfo", O_RDONLY) = 170
[pid 3321] open("/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 175
[pid 3321] open("/tmp/", O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC) = 175
[pid 3321] open("/tmp/data.txt", O_RDONLY) = 175
[pid 3321] open("/tmp/data.txt", O_RDONLY|O_DIRECT) = -1 EINVAL (Invalid argument)
open()失败,因为tmpfs文件系统不支持O_DIRECT。所以我在根目录中移动了文件,并使其可以访问:
# ll /data.txt
-rw-rw-rw- 1 root root 30M Feb 20 02:28 /data.txt
# ll /data.txt
-rw-rw-rw- 1 root root 30M Feb 20 02:28 /data.txt
# sqlcmd -S localhost -d leak -U sa -Q "BULK INSERT leak FROM '/data.txt'"
Msg 4860, Level 16, State 1, Server mssql, Line 1
Cannot bulk load. The file "/data.txt" does not exist or you don't have file access rights.
但这次服务器甚至没有尝试访问该文件。将文件移动到除root之外的世界可访问目录中,修复它:
# sqlcmd -S localhost -d leak -U sa -Q "BULK INSERT leak FROM '/media/data.txt'"
(1000000 rows affected)