Oracle数据库中XMLTYPE列中的XML编码

Oracle数据库中XMLTYPE列中的XML编码,xml,oracle,character-encoding,oracle12c,toad,Xml,Oracle,Character Encoding,Oracle12c,Toad,我创建了一个如下表: create table b (data timestamp, value XMLTYPE); 我在TOAD12.6中运行这个脚本,将XML存储在表中 DECLARE lc_Soap CLOB; lc_Request CLOB; px_RequestXML XMLTYPE := XMLTYPE ('<test><test1>ABDDÇJJSõ</test1></

我创建了一个如下表:

create table b (data timestamp, value XMLTYPE);
我在TOAD12.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;
但该脚本是为在不同的DB用户或Oracle作业中运行而构建的。在这种情况下,编码是不同的:

<?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>

试验
阿布德·切杰什(ABDDõJJSõ)
DB的
NLS_字符集
参数为WE8MSWIN1252。
为什么会这样?我可以始终将谁存储为UTF-8?

当在从客户端发送到DB的内容中包含非ASCII字符时(例如ABDDõJJSõ),可能需要将客户端字符集转换为DB字符集。如果客户端对正在使用的字符集不正确,或者数据库无法处理字符,那么这可能会变得复杂。如果内容来自某个文件,那么在处理该文件时,还存在其他应用程序错误理解字符集的风险(例如版本控制)

使用任何潜在问题字符的编码版本通常更安全。您可以使用ASCISTR获取字符串的明确转换版本,并使用UNISTR将其转换回

select asciistr('Çõ'), unistr('\00C7\00F5') from dual;
您甚至可以检查字符是否按预期转换


如果脚本中没有非ascii字符,则可以消除许多潜在问题。可能仍然存在问题,但诊断起来会更容易。

Oracle将使用客户端字符集从CLOB或字符串创建
XMLTYPE
,并完全忽略XML prolog中的编码(请参阅)。您可以设置
encoding=“blabla”
,它就会工作。只有当您从BLOB创建XMLTYPE时,Oracle才会接受XML序言中的编码

在读取
XMLTYPE
时,客户机环境还驱动编码。如果希望XML文档以UTF-8编码,而不考虑客户机编码,则必须将其检索为BLOB

通过
getBlobVal()

或者通过
xmlserialize()


我不知道为什么这真的是一个问题,因为如果你有DB字符集以外的字符,你会有其他问题;但是,在XMLType中使用DB char集进行编码的唯一方法似乎是。也许a到UTF-8我发现在执行SELECT语句时可以看到UTF-8编码,但在TOAD中,我选择F4和数据TabGary时可以看到原始编码,但我的重点是“他为什么以及如何更改xml内容上的编码头参数?”
select asciistr('Çõ'), unistr('\00C7\00F5') from dual;
SELECT (c2).getBlobVal(nls_charset_id('UTF8')) FROM b;
SELECT xmlserialize(DOCUMENT c2 AS BLOB ENCODING 'UTF-8') FROM b;