我正在尝试从CLOB列创建XMLTYPE并明确指定字符集。我发现有一个重载的XMLTYPE.createXML函数接受字符集,但是当我执行传递其他参数时,我得到一个错误。为什么呢?
const obs1 = this.http.get(`${API_URL}/transitions`);
const obs2 = this.http.get(`${API_URL}/states`);
Observable.merge(obs1, obs2).subscribe()
错误:
ORA-06553:PLS-306:调用的参数的数量或类型错误 'CREATEXML'
我打扰传递字符集的原因是,CLOB列包含使用与数据库字符集不同的字符集编码的字符(例如,它不支持#180)。
答案 0 :(得分:1)
我打扰传递字符集的原因是,CLOB列包含使用与数据库字符集不同的字符集编码的字符(例如,它不支持#180)。
这个我不明白。 #180;
是简单的纯ASCII,它适用于任何条件。
简单地运行
SELECT
XMLTYPE.createXML(TO_CLOB('<node1><node2>the ´ character</node2></node1>'))
from dual;
甚至更短
SELECT
XMLTYPE('<node1><node2>the ´ character</node2></node1>')
from dual;
现在,让我们假设您的XML包含数据库字符集不支持的字符,在这种情况下,您的XML可能是<node1><node2>the ´ character</node2></node1>
。
首先,您无法存储(或使用)CLOB
(或VARCHAR2
)中数据库字符集不支持的任何字符 - 从不!您必须使用基于国家数据库字符集的NCLOB
(或NVARCHAR2
),并且通常支持任何Unicode字符。
您可以在XMLTYPE.createXML()
中指定字符集,但是必须将XML作为BLOB提供。你可以这样做:
DECLARE
xmlString NCLOB := '<node1><node2>the '||NCHR(180)||' character</node2></node1>';
xmlDoc XMLTYPE;
xmlBinary BLOB;
lang_context INTEGER := DBMS_LOB.DEFAULT_LANG_CTX;
dest_offset INTEGER := 1;
src_offset INTEGER := 1;
read_offset INTEGER := 1;
warning INTEGER;
BEGIN
DBMS_LOB.CREATETEMPORARY(xmlBinary, TRUE);
DBMS_LOB.CONVERTTOBLOB(xmlBinary, xmlString, DBMS_LOB.LOBMAXSIZE, dest_offset, src_offset, 2000, lang_context, warning);
xmlDoc := XMLTYPE.createXML(xmlBinary, 2000, NULL, 1, 1);
END;
2000是您的国家数据库字符集的csid。使用
SELECT PARAMETER, VALUE, NLS_CHARSET_ID(VALUE)
FROM NLS_DATABASE_PARAMETERS
WHERE PARAMETER LIKE '%CHARACTERSET';
获取您的身份证。
一些注意事项:
我尝试使用字符串N'<node1><node2>the ´ character</node2></node1>'
,但Oracle立即用´
替换¿
。我无法直接输入´
。
几乎所有XML Functions返回VARCAHR2
值(不是NVARCAHR2
),大多数XMLTYPE
成员函数也与CLOB
一起使用(不是NCLOB
)。如果您只是将XML文档作为XMLTYPE
读取并存储在数据库中,那么它应该没问题,但是一旦您使用这些数据开始任何操作,您迟早会遇到转换错误。您应该考虑迁移数据库字符集,请参阅Character Set Migration和/或Oracle Database Migration Assistant for Unicode
答案 1 :(得分:0)
您可以直接使用XMLType
功能
SELECT XMLTYPE('<?xml version="1.0" encoding="UTF-8"?>'
||TO_CLOB ('<node1><node2>the ´ character</node2></node1>')) myxml
FROM dual;