Oracle Stored Proc 插入编码数据

Oracle Stored Proc inserting encoded data

我正在调查为什么我们会在数据库中获取一些编码数据。

我发现我们正在使用的网格正在向传递给存储过程的 xml 数据添加一些 HTML 编码。

但是,我已经关闭了数据表中的 html 编码,并确认我们正在向数据库发送未编码的数据。但是,inserts/updates 数据的存储过程似乎仍在编码单引号。

我在存储过程中没有看到任何说明它对数据进行编码的内容。是否有可能导致此问题的设置或其他可以与 xml 一起发送的设置或其他内容。

CREATE OR REPLACE PROCEDURE spSample (ncoXml IN XMLTYPE)
IS

正在使用 utf-8 编码发送 xml。我猜这是问题所在。

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

感谢您提供的任何帮助或建议。

您的过程参数是 XMLtype,它自动编码单引号和双引号,来自 predefined XML entities list

SQL> select xmltype('<test>6''4"</test>') from dual;

XMLTYPE('<TEST>6''4"</TEST>')
--------------------------------------------------------------------------------
<test>6&apos;4&quot;</test>

这与HTML无关;其他非XML HTML entities 不编码。你所看到的是正确的;实体应在您的 XMLType 对象中编码。

如果您想查看解码后的实体,您可以使用已弃用的 extractvalue 函数:

SQL> select extractvalue(xmltype('<test>6''4"</test>'), '/test') from dual;

EXTRACTVALUE(XMLTYPE('<TEST>6''4"</TEST>'),'/TEST')
--------------------------------------------------------------------------------
6'4"

或一个 XML 查询,使用 XMLCast 进行解码,作为转换为纯字符串的一部分:

SQL> select xmlcast(xmlquery('/test/text()' passing xmltype('<test>6''4"</test>')
  2  returning content) as varchar2(10)) from dual;

XMLCAST(XM
----------
6'4"

根据您在程序中使用数据的方式,您可以将使用 extract() 的形式更改为 xmlcast(xmlquery(...) as ...)。您不能在 PL/SQL 中本地调用它(据我所知),因此您需要将上下文从 dual 切换到 select;而且它似乎也不喜欢在命令中连接索引值 - 不太清楚为什么,但我不得不使用一个变量来保存构造的 XPath。

例如,如果您有类似的东西 - 在您的真实情况下将值传递给您的过程 - 您仍然会有编码值:

DECLARE
  ncoXml XMLType := XMLType(q'[<victims><victim index="1"><name>Peter O'Toole</name></victim></victims>]');
  victimIndex pls_integer := 1;
  victimName varchar2(200);
BEGIN
  victimName := SUBSTR(ncoXml.EXTRACT('/victims/victim[@index="'
    || TO_CHAR(victimIndex) || '"]/name/text()').GETSTRINGVAL(), 1, 200);
  dbms_output.put_line(victimName);
END;
/

Peter O&apos;Toole

并且 XMLCast 变体可能如下所示:

DECLARE
  ncoXml XMLType := XMLType(q'[<victims><victim index="1"><name>Peter O'Toole</name></victim></victims>]');
  victimIndex pls_integer := 1;
  victimName varchar2(200);
  xPath varchar2(200);
BEGIN
  xPath := '/victims/victim[@index="' || victimIndex || '"]/name/text()';
  select xmlcast(xmlquery(xPath passing ncoXml returning content) as varchar2(200))
  into victimName
  from dual;
  dbms_output.put_line(victimName);
END;
/

Peter O'Toole