Oracle Stored Proc插入编码数据

时间:2015-04-27 12:39:55

标签: xml oracle stored-procedures utf-8 oracle11g

我正在研究为什么我们在数据库中获取一些编码数据。

我发现我们使用的网格是将一些HTML编码添加到传递给存储过程的xml数据中。

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

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

CREATE OR REPLACE PROCEDURE spSample (ncoXml IN XMLTYPE)
IS

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

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

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

1 个答案:

答案 0 :(得分:1)

您的过程参数是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"

或XMLQuery,使用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中本地调用它(据我所知),所以你需要一个上下文切换来从双重选择;并且它似乎也不喜欢在命令中连接索引值 - 不太确定原因,但是我必须使用变量来保存构造的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