在 Java 中创建一个文件,以便使用 BCP 和 UTF-16 加载到 SQLServer 2005 中的 nvarchar 字段

StackOverflow https://stackoverflow.com/questions/2246355

我想使用 BCP 使用加载程序控制文件加载到具有 nvarchar 字段的 SQL Server 2005 表中。据我了解,SQL Server 2005仅支持UTF-16(我相信它是UTF-16 LE)。该文件正在由 Java 程序输出。我目前的设置方式如下:

  1. XML 格式的 BCP 加载程序文件(使用以下命令创建:bcp test_table format nul -c -x -T -f test_table.xml -S server)

  2. Java 程序使用以下代码编写输出:

    File f = new File("from_java.txt");
    String encoding = "x-UTF-16LE-BOM";
    OutputStream os = new FileOutputStream(f);
    OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os, encoding);
    String theString = "áááááLittle Endian, BOM\r\n";
    outputStreamWriter.append(theString);
    outputStreamWriter.flush();
    outputStreamWriter.close();
    
  3. 然后使用以下 bcp 命令:
    bcp test_table in from_java.txt -T -f test_table.xml -S server -error error.txt

我在表中得到的是 ÿþá. 。并不是 áááááLittle Endian, BOM

我尝试了更改参数的几种不同排列:

  • 改变我生成加载器控制文件的方式(使用 -n 表示本机数据而不是 -c 表示字符数据...我认为这可能与它有关,但我没有看到插入的数据有任何改进)
  • 尝试了几种不同形式的UTF-16编码,包括大端和无BOM的小端,但无济于事
  • 尝试在文件中手动输出 BOM,因为我在某处读到 Microsoft 非常喜欢使用 BOM 信息
  • 考虑尝试将文件输出为 UCS-2(而不是 UTF-16),因为这(显然)是 BCP 实际读取文件的内容
  • 在 bcp 导入上尝试了 -w ,这确实有效,但不能与加载程序格式文件结合使用(有没有办法将告诉 BCP 文件以 UTF-16 编码的任何魔法合并到格式文件中?)
  • 如果我在 windows-1252 中输出文件并将该代码页指定为 -c 1252 当我加载文件时选择 bcp (但我不想这样做,因为我会丢失信息,因为 UTF-16 是与 1252 相比可以表示的超集)

有没有人设法使用 UTF-16 数据结合加载程序格式配置文件将 bcp 加载到 nvarchar 字段中?

提前致谢,

-詹姆士

有帮助吗?

解决方案

我对这些回应确实感到不知所措,但我已经破解了它。

加载文件需要生成 -w flag,所以生成文件的命令是:

bcp <table> format nul -w -x T -f loader-control-w-format.xml -S <server> -t "||"

这会导致加载程序控制文件看起来有点不同,您会得到如下条目:

<FIELD ID="1" xsi:type="NCharTerm" TERMINATOR="|\0|\0" MAX_LENGTH="1000" COLLATION="SQL_Latin1_General_CP1_CI_AS"/>

请注意分隔符列为 |\0|\0, ,零对应于文件中的额外字节,因为 UTF-16(或微软(错误地)称之为“unicode”)是双字节字符编码。

对于以这种方式处理 BCP 的其他人,请注意以下几点:

  • 当 SQLServer 谈到“本机”时,他们指的是本机字符,即重音字符
  • 当 SQLServer 谈到 Unicode 时,他们实际上指的是 UTF16(Little Endian)编码方式 统一字符集. 。这就是 -w 的作用
  • 当使用 UTF-16 写入要加载到 BCP 的文件时,该文件必须采用 UTF-16 Little Endian 格式,并且不能包含 UTF BOM(因为 BCP 会将其解释为应该加载的字节,并且您的第一条记录将包含BOM,呃!)

以UTF-16格式写出可以通过这种方式加载的文件的Java代码如下:

    final File f = new File("C:\\temp\\bcp_prob\\from_java-UTF-16.txt");
    //LE with no BOM is important here:
    final String encoding = "UTF-16LE";
    final OutputStream os = new FileOutputStream(f);
    final OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os, encoding);
    final String theString = "UTF-16-LE, intermetálico básicos intermetálico película magnética dinámicos||another_col\r\n";        
    outputStreamWriter.append(theString);
    outputStreamWriter.flush();
    outputStreamWriter.close();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top