Создайте файл на Java для загрузки в поле nvarchar в SQLServer 2005, используя BCP и UTF-16.

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

Вопрос

Я хочу использовать BCP для загрузки в таблицу SQL Server 2005 с полем nvarchar с использованием файла управления загрузчиком.Насколько я понимаю, SQL Server 2005 поддерживает только UTF-16 (и я считаю, что это UTF-16 LE).Файл выводится программой Java.На данный момент у меня это настроено следующим образом:

  1. Файл загрузчика BCP в формате XML (созданный с помощью следующей команды: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, включая прямой и прямой порядок байтов без спецификации, но безрезультатно.
  • попытался вывести спецификацию вручную в файл, поскольку где-то читал, что Microsoft действительно любит использовать информацию о спецификации
  • рассмотрел попытку вывода файла как UCS-2 (вместо UTF-16), поскольку это (очевидно) то, что BCP на самом деле читает файл как
  • попробовал -w при импорте bcp, это работает, но не в сочетании с файлом формата загрузчика (есть ли способ включить в файл формата любую магию, сообщающую BCP, что файл закодирован в UTF-16?)
  • Я смогу заставить его работать, если выведу файл в Windows-1252 и укажу эту кодовую страницу как -c 1252 опция bcp при загрузке файла (но я не хочу этого делать, так как буду терять информацию, поскольку UTF-16 — это расширенный набор того, что можно представить по сравнению с 1252)

Кому-нибудь удалось заставить bcp загрузиться в поле nvarchar, используя данные UTF-16 в сочетании с файлом конфигурации формата загрузчика?

Заранее спасибо,

-Джеймс

Это было полезно?

Решение

Я был буквально завален ответами, но мне удалось разобраться.

Файл загрузчика должен быть сгенерирован с помощью -w флаг, поэтому команда для создания файла:

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 (или просто «Юникод», как его (ошибочно) называет Microsoft) — это двухбайтовая кодировка символов.

Несколько замечаний для здравомыслия тех, кто имеет дело с BCP таким образом:

  • Когда SQLServer говорит о «родных», они имеют в виду собственные символы, т.е.акцентированные символы
  • Когда SQLServer говорит о Unicode, на самом деле они имеют в виду способ кодирования UTF16 (Little Endian). Набор символов Юникода.Вот к чему относится -w
  • При записи файла для загрузки в BCP с использованием UTF-16 файл должен быть в формате UTF-16 Little Endian и не может содержать спецификацию UTF (поскольку BCP интерпретирует это как байт, который должен быть загружен, и ваша первая запись будет содержать БОМ, ух!)

Код Java для записи файла в формате UTF-16, который можно загрузить таким образом, выглядит следующим образом:

    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