Oracle xmltable 解析 return LPX-00209
Oracle xmltable parsing return LPX-00209
我是 Oracle 的新手。现在我正在尝试解析 XML 并将其放入 VK_ACCOUNTS table 中。
我的 xml 样本在这里:
<?xml version="1.0" encoding="utf-8"?>
<response list="true">
<account>
<account_id>1656672360</account_id>
<account_type>general</account_type>
<account_status>1</account_status>
<access_role>reports</access_role>
</account>
</response>
我要求 xml 具有以下功能,据我所知 returns xml 正确:
create or replace function GET_CLOBFROMURL(
p_url varchar2,
p_charset varchar2 default 'UTF8'
) return clob
is
req utl_http.req;
resp utl_http.resp;
val varchar2(32547);
a clob;
BEGIN
a:='';
dbms_lob.createtemporary(a,true);
dbms_lob.open(a,dbms_lob.lob_readwrite);
req := utl_http.begin_request(p_url);
utl_http.set_body_charset(req, p_charset);
resp := utl_http.get_response(req);
LOOP
a := a||val;
utl_http.read_text(resp, val, 5000);
END LOOP;
utl_http.end_response(resp);
return a;
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
return a;
WHEN others then
utl_http.end_response(resp);
raise;
END;
并得到 xml 到 xml_clob
xml_clob := tableau.get_clobFromUrl(REQUEST);
IF xml_clob != EMPTY_CLOB() THEN
insert into tableau.VK_ACCOUNTS(account_id, account_type, account_status, access_role)
SELECT
proc.account_id,
proc.account_type,
proc.account_status,
proc.access_role
FROM XMLTABLE('response/account' passing (select xmltype(xml_clob) resp FROM dual)
columns account_id number path '/account/account_id',
account_type varchar2(20) path '/account/account_type',
account_status number path '/account/account_status',
access_role varchar2(20) path '/account/access_role'
) proc;
COMMIT;
END IF;
END;
最后我得到一个错误:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML
LPX-00209: PI names starting with XML are reserved
Error at line 3
ORA-06512: на "SYS.XMLTYPE", line 272
ORA-06512: на line 1
ORA-06512: на "TABLEAU.VK_LOADDATA", line 11
ORA-06512: на line 2
我已经尝试过 TRIM XML 的功能,但它对我没有帮助。
有什么想法吗?
LPX-00209: PI names starting with XML are reserved
当 XML 字符串中有前导空白字符时似乎会发生。
See http://oraclequirks.blogspot.co.uk/2013/03/lpx-00209-pi-names-starting-with-xml.html.
您应该可以通过以下方式解决它:
XMLType( TRIM( xml_clob ) )
稍微简化您的函数:
create or replace function GET_CLOBFROMURL(
p_url varchar2,
p_charset varchar2 default 'UTF8'
) return clob
is
req utl_http.req;
resp utl_http.resp;
val varchar2(32547);
a clob := EMPTY_CLOB();
BEGIN
req := utl_http.begin_request(p_url);
utl_http.set_body_charset(req, p_charset);
resp := utl_http.get_response(req);
LOOP
BEGIN
utl_http.read_text(resp, val, 5000);
a := a||val;
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
EXIT;
END;
END LOOP;
return a;
EXCEPTION
WHEN others THEN
utl_http.end_response(resp);
RAISE;
END;
那么插入完全可以在SQL:
中完成
insert into tableau.VK_ACCOUNTS (
account_id,
account_type,
account_status,
access_role
)
SELECT proc.account_id,
proc.account_type,
proc.account_status,
proc.access_role
FROM ( SELECT tableau.get_clobFromUrl(REQUEST) AS xml FROM DUAL ) c,
XMLTABLE(
'/response/account'
passing XMLType( TRIM( c.xml ) )
columns account_id number path './account_id',
account_type varchar2(20) path './account_type',
account_status number path './account_status',
access_role varchar2(20) path './access_role'
) proc
WHERE c.xml IS NOT NULL
AND DBMS_LOB.GETLENGTH( c.xml ) > 0;
我知道 3 种重复此异常的方法。
- Prolog 在 xml 中存在不止一次。
select xmltype('<?xml version="1.0" ?><?xml version="1.0" ?><a></a>') from dual;
- Prolog 不是 xml 的第一个元素。 .
select xmltype('<a></a><?xml version="1.0" ?>') from dual;
- 同样的情况,但是xml的第一行是空的。
select xmltype(chr(10)||chr(13)||'<?xml version="1.0" ?><a></a>') from dual;
我认为您遇到了第 1 号问题。 3.快速摆脱空第一行的方法。是鲜为人知的函数形式 TRIM
.
select xmltype( trim(leading chr(13) from trim(leading chr(10) from trim(' '||chr(10)||chr(13)||' <?xml version="1.0" ?><a></a>')))) from dual;
trim(leading chr(13) from trim(leading chr(10) from trim('your_xml_clob')))
它应该像这样工作
xml_clob := tableau.Get_Clobfromurl();
s := SUBSTR(xml_clob,INSTR(xml_clob,'<'));
我是 Oracle 的新手。现在我正在尝试解析 XML 并将其放入 VK_ACCOUNTS table 中。 我的 xml 样本在这里:
<?xml version="1.0" encoding="utf-8"?>
<response list="true">
<account>
<account_id>1656672360</account_id>
<account_type>general</account_type>
<account_status>1</account_status>
<access_role>reports</access_role>
</account>
</response>
我要求 xml 具有以下功能,据我所知 returns xml 正确:
create or replace function GET_CLOBFROMURL(
p_url varchar2,
p_charset varchar2 default 'UTF8'
) return clob
is
req utl_http.req;
resp utl_http.resp;
val varchar2(32547);
a clob;
BEGIN
a:='';
dbms_lob.createtemporary(a,true);
dbms_lob.open(a,dbms_lob.lob_readwrite);
req := utl_http.begin_request(p_url);
utl_http.set_body_charset(req, p_charset);
resp := utl_http.get_response(req);
LOOP
a := a||val;
utl_http.read_text(resp, val, 5000);
END LOOP;
utl_http.end_response(resp);
return a;
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
return a;
WHEN others then
utl_http.end_response(resp);
raise;
END;
并得到 xml 到 xml_clob
xml_clob := tableau.get_clobFromUrl(REQUEST);
IF xml_clob != EMPTY_CLOB() THEN
insert into tableau.VK_ACCOUNTS(account_id, account_type, account_status, access_role)
SELECT
proc.account_id,
proc.account_type,
proc.account_status,
proc.access_role
FROM XMLTABLE('response/account' passing (select xmltype(xml_clob) resp FROM dual)
columns account_id number path '/account/account_id',
account_type varchar2(20) path '/account/account_type',
account_status number path '/account/account_status',
access_role varchar2(20) path '/account/access_role'
) proc;
COMMIT;
END IF;
END;
最后我得到一个错误:
ORA-31011: XML parsing failed
ORA-19202: Error occurred in XML
LPX-00209: PI names starting with XML are reserved
Error at line 3
ORA-06512: на "SYS.XMLTYPE", line 272
ORA-06512: на line 1
ORA-06512: на "TABLEAU.VK_LOADDATA", line 11
ORA-06512: на line 2
我已经尝试过 TRIM XML 的功能,但它对我没有帮助。
有什么想法吗?
LPX-00209: PI names starting with XML are reserved
当 XML 字符串中有前导空白字符时似乎会发生。 See http://oraclequirks.blogspot.co.uk/2013/03/lpx-00209-pi-names-starting-with-xml.html.
您应该可以通过以下方式解决它:
XMLType( TRIM( xml_clob ) )
稍微简化您的函数:
create or replace function GET_CLOBFROMURL(
p_url varchar2,
p_charset varchar2 default 'UTF8'
) return clob
is
req utl_http.req;
resp utl_http.resp;
val varchar2(32547);
a clob := EMPTY_CLOB();
BEGIN
req := utl_http.begin_request(p_url);
utl_http.set_body_charset(req, p_charset);
resp := utl_http.get_response(req);
LOOP
BEGIN
utl_http.read_text(resp, val, 5000);
a := a||val;
EXCEPTION
WHEN utl_http.end_of_body THEN
utl_http.end_response(resp);
EXIT;
END;
END LOOP;
return a;
EXCEPTION
WHEN others THEN
utl_http.end_response(resp);
RAISE;
END;
那么插入完全可以在SQL:
中完成insert into tableau.VK_ACCOUNTS (
account_id,
account_type,
account_status,
access_role
)
SELECT proc.account_id,
proc.account_type,
proc.account_status,
proc.access_role
FROM ( SELECT tableau.get_clobFromUrl(REQUEST) AS xml FROM DUAL ) c,
XMLTABLE(
'/response/account'
passing XMLType( TRIM( c.xml ) )
columns account_id number path './account_id',
account_type varchar2(20) path './account_type',
account_status number path './account_status',
access_role varchar2(20) path './access_role'
) proc
WHERE c.xml IS NOT NULL
AND DBMS_LOB.GETLENGTH( c.xml ) > 0;
我知道 3 种重复此异常的方法。
- Prolog 在 xml 中存在不止一次。
select xmltype('<?xml version="1.0" ?><?xml version="1.0" ?><a></a>') from dual;
- Prolog 不是 xml 的第一个元素。 .
select xmltype('<a></a><?xml version="1.0" ?>') from dual;
- 同样的情况,但是xml的第一行是空的。
select xmltype(chr(10)||chr(13)||'<?xml version="1.0" ?><a></a>') from dual;
我认为您遇到了第 1 号问题。 3.快速摆脱空第一行的方法。是鲜为人知的函数形式 TRIM
.
select xmltype( trim(leading chr(13) from trim(leading chr(10) from trim(' '||chr(10)||chr(13)||' <?xml version="1.0" ?><a></a>')))) from dual;
trim(leading chr(13) from trim(leading chr(10) from trim('your_xml_clob')))
它应该像这样工作
xml_clob := tableau.Get_Clobfromurl();
s := SUBSTR(xml_clob,INSTR(xml_clob,'<'));