Кодировка XML в столбце XMLTYPE в БД Oracle - PullRequest
0 голосов
/ 24 мая 2018

У меня есть таблица, созданная следующим образом:

create table b (data timestamp, value XMLTYPE);

Я запускаю этот скрипт в TOAD 12.6 для сохранения XML в таблице.

DECLARE
    lc_Soap         CLOB;
    lc_Request      CLOB;
    px_RequestXML   XMLTYPE
        := XMLTYPE ('<test><test1>ABDDÇJJSõ</test1></test>');
BEGIN
    DELETE b;

    lc_Soap :=
        '<?xml version="1.0" encoding="ISO-8859-1"?>
               <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
                  <s:Header>
                      <h:AxisValues xmlns="urn:/microsoft/multichannelframework/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="urn:/microsoft/multichannelframework/">
                          <User xmlns="">TEST</User>
                      </h:AxisValues>
                  </s:Header>
                  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                      <substr/>
                  </s:Body>
              </s:Envelope>';

    lc_Request :=
        pkg_utils.replace_clob (lc_Soap,
                                '<substr/>',
                                xml_utils.XMLTypeToClob (px_RequestXML));

    px_RequestXML := XMLTYPE.createXML (lc_Request);

    INSERT INTO b
         VALUES (SYSTIMESTAMP, px_RequestXML);

    COMMIT;
END;

Когда я пытаюсь увидеть, чтов столбце VALUE я получаю эту кодировку UTF-8

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:AxisValues xmlns="urn:/microsoft/multichannelframework/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="urn:/microsoft/multichannelframework/">
      <User xmlns="">TEST</User>
    </h:AxisValues>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <test>
      <test1>ABDDÇJJSõ</test1>
    </test>
  </s:Body>
</s:Envelope>

Но этот сценарий был создан для запуска в другом пользователе БД или в Oracle JOB.И в этом случае кодировка отличается:

<?xml version="1.0" encoding="WINDOWS-1252"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:AxisValues xmlns="urn:/microsoft/multichannelframework/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:h="urn:/microsoft/multichannelframework/">
      <User xmlns="">TEST</User>
    </h:AxisValues>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <test>
      <test1>ABDDÇJJSõ</test1>
    </test>
  </s:Body>
</s:Envelope>

Параметр NLS_CHARACTERSET для БД - WE8MSWIN1252.Почему это добавить?И кого я могу всегда хранить как UTF-8?

Ответы [ 2 ]

0 голосов
/ 26 мая 2018

Oracle будет использовать клиентский набор символов для создания XMLTYPE из CLOB или String и полностью игнорировать кодировку в прологе XML (см. docs ).Вы можете установить encoding="blabla", и это будет работать.Oracle соблюдает кодировку в прологе XML, только когда вы создаете XMLTYPE из BLOB.

Клиентская среда также управляет кодированием при чтении XMLTYPE.Если вы хотите, чтобы XML-документ был закодирован в UTF-8 независимо от кодировки клиента, вы должны извлечь его как BLOB.

Либо через getBlobVal()

SELECT (c2).getBlobVal(nls_charset_id('UTF8')) FROM b;

, либо через xmlserialize()

SELECT xmlserialize(DOCUMENT c2 AS BLOB ENCODING 'UTF-8') FROM b;
0 голосов
/ 25 мая 2018

Когда вы включаете символы не ASCII в контент, отправляемый от клиента в БД (например, ABDDÇJJSõ), может потребоваться преобразование из набора символов клиента в набор символов БД.Это может осложниться, если клиент неверно использует используемый набор символов или база данных не может обработать символы.Если содержимое происходит из файла, существует также риск того, что какое-то другое приложение неправильно поймет набор символов при обработке файла (например, управление версиями)

Часто безопаснее использовать зашифрованные версии любых потенциальных проблемных символов,Вы можете использовать ASCIISTR, чтобы получить однозначную преобразованную версию строки, и UNISTR, чтобы преобразовать ее обратно.

select asciistr('Çõ'), unistr('\00C7\00F5') from dual;

Вы можете даже проверить, преобразованы ли символы, как вы ожидаете.

http://www.fileformat.info/info/unicode/char/00c7/index.htm http://www.fileformat.info/info/unicode/char/00f5/index.htm

Если в скрипте нет символов, отличных от ascii, вы устраняете много потенциальных проблем.Могут быть проблемы, но их будет легче диагностировать.

...