我正在研究为什么我们在数据库中获取一些编码数据。
我发现我们使用的网格是将一些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"?>
感谢您提供任何帮助或建议。
答案 0 :(得分:1)
您的过程参数是XMLtype,它自动编码来自predefined XML entities list
的单引号和双引号SQL> select xmltype('<test>6''4"</test>') from dual;
XMLTYPE('<TEST>6''4"</TEST>')
--------------------------------------------------------------------------------
<test>6'4"</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'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