我有一个纯文本数据文件,其中包含由不可打印字符"File Separator" (0x1c) 分隔的字段的记录。我正在尝试使用 SQL Server 的 bcp 实用程序将此数据加载到我的数据库中。然而,当使用文件分隔符的十六进制编码值作为 TERMINATOR 时,我得到一个语法错误。
我试过使用
- 十六进制编码值:
"0x1c"
- XML 编码值作为十六进制:
""
- XML 编码值作为十进制:
""
这些都不起作用,但是当对可打印字符使用相同的编码时,例如tab
,这确实起作用:	
, 	
(0x9
不起作用。不足为奇,因为这是一个 XML 文件。)
结论似乎是不支持不可打印的字符。是这样吗?这将具有讽刺意味,因为不可打印的分隔符正是为此目的而创建的......
您可以在下面找到重现此问题的所有代码:
XML格式文件:test.xml
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="" MAX_LENGTH="10" COLLATION="Latin1_General_CS_AS_WS"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="41"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="COL1" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="2" NAME="COL2" xsi:type="SQLNUMERIC" PRECISION="4" SCALE="0"/>
</ROW>
</BCPFORMAT>
数据文件:test.txt
这只是一行,作为一个测试用例。StackExchange 没有在下面的行中显示分隔符,但是当您单击此帖子的“编辑”时,分隔符已包含在内,您应该可以复制粘贴它。
1111111112008
命令行
bcp TEST_DB.dbo.UL_TEST in "test.txt" -T -f "test.xml"
从有关BCP - Specify Field and Row Terminators (SQL Server)的文档看来,不支持不可打印的字符:
作为一个选项,您可以使用
POWERSHELL
读取源文件并0x1C
使用其他字符(如 tilda (~))搜索\替换字符并输出到不同的文件。然后使用该字符作为你的终结者。由于@ScottHodgin 指出不支持不可打印的字符,因此在源文件中替换它们是唯一的选择。
您可以在下面找到一个示例 PowerShell 脚本,该脚本可以对以 UTF8 编码的文件进行此替换(带或不带 BOM 标头无关紧要),并写入以 UTF8 编码的不带 BOM 标头的输出文件。
此外,它使用 AppendAllLines 将其转换为流式操作。这种方式也适用于大文件,因为在替换之前不必将它们完全加载到内存中。-ReadCount 1000 大大加快了这个过程。
确保将上面的脚本保存在使用带有BOM 标头的 UTF8 编码的文件中,否则 PowerShell 不会将字符处理为 UTF-8。