在PL/SQL中测试xmltype变量(不在table中)是否存在值(节点存在?)
Test whether value exists (node exists?) in xmltype variable (not in table) in PL/SQL
我在 PL/SQL 中有一个来自 SOAP 调用的结果变量,我得到的输出类型变量是 xmltype(没有写包或过程,不要得到改变它)。返回的变量类型是xmltype,想看看有没有结果。我无法理解 PL/SQL.
中 XML 周围的文档
账号会一直存在,我看的是位置有没有返回。或者不止一个被退回(这会很糟糕,但我应该检查一下)。
结果看起来像
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:Action>http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule//CustomerAccountService/findCustomerAccountResponse</wsa:Action>
<wsa:MessageID>urn:uuid:7dd64ecf-676f-4667-a761-dc7603e99929</wsa:MessageID>
</env:Header>
<env:Body>
<ns0:findCustomerAccountResponse xmlns:ns0="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule/types/">
<ns0:result xsi:type="ns2:CustomerAccountResult" xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/" xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns4="http://xmlns.oracle.com/apps/cdm/foundation/parties/partyService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns9="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccount/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:Message>
<tns:code>25089</tns:code>
<tns:message>JBO-25089: Too many matching records found. Specify additional criteria to limit the number of records.</tns:message>
<tns:severity>SEVERITY_WARNING</tns:severity>
</ns1:Message>
<ns2:Value>
<ns2:AccountNumber>XXXXX</ns2:AccountNumber>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/">
<ns2:CustomerAccountSiteUse xmlns:ns6="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSiteUse/">
<ns2:Location>XXXXXXXX</ns2:Location>
</ns2:CustomerAccountSiteUse>
</ns2:CustomerAccountSite>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
</ns2:Value>
</ns0:result>
</ns0:findCustomerAccountResponse>
</env:Body>
</env:Envelope>
我觉得像
IF DBMS_LOB.INSTR(xml_response.getClobVal(), 'Location>XXXXXX<') > 0 THEN
val_returned := TRUE;
END IF;
会起作用,但我认为这可能是一种糟糕的方法?我一直在尝试阅读文档,但他们都提到从 table 等中执行 selects,而我没有 table。我可以在这些东西上使用 xml 表达式而不引用 table 吗?我必须 select 来自 dual 还是什么?
是的,Oracle 中的 XPath 并不漂亮,尤其是在涉及名称空间的情况下。我不擅长,但也许这会让你朝着正确的方向开始:
DECLARE
accountnumber VARCHAR2(100);
location VARCHAR2(100);
x XMLType := XMLType('
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:Action>http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule//CustomerAccountService/findCustomerAccountResponse</wsa:Action>
<wsa:MessageID>urn:uuid:7dd64ecf-676f-4667-a761-dc7603e99929</wsa:MessageID>
</env:Header>
<env:Body>
<ns0:findCustomerAccountResponse xmlns:ns0="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule/types/">
<ns0:result xsi:type="ns2:CustomerAccountResult" xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/" xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns4="http://xmlns.oracle.com/apps/cdm/foundation/parties/partyService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns9="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccount/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:Message>
<tns:code>25089</tns:code>
<tns:message>JBO-25089: Too many matching records found. Specify additional criteria to limit the number of records.</tns:message>
<tns:severity>SEVERITY_WARNING</tns:severity>
</ns1:Message>
<ns2:Value>
<ns2:AccountNumber>XXXXX</ns2:AccountNumber>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/">
<ns2:CustomerAccountSiteUse xmlns:ns6="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSiteUse/">
<ns2:Location>XXXXXXXX</ns2:Location>
<ns2:Location>YYYYYYYY</ns2:Location>
</ns2:CustomerAccountSiteUse>
</ns2:CustomerAccountSite>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
</ns2:Value>
</ns0:result>
</ns0:findCustomerAccountResponse>
</env:Body>
</env:Envelope>
');
BEGIN
SELECT EXTRACT(x, '//ns2:AccountNumber/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO accountnumber FROM DUAL;
dbms_output.put_line('accountnumber:'||accountnumber);
SELECT EXTRACT(x, '//ns2:Location/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO location FROM DUAL;
dbms_output.put_line('locations:'||location);
SELECT EXTRACT(x, '//ns2:Location[2]/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO location FROM DUAL;
dbms_output.put_line('location2:'||location);
SELECT EXTRACT(x, '//ns2:Location[3]/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO location FROM DUAL;
dbms_output.put_line('location3:'||location);
END;
/
这将输出
accountnumber:XXXXX
locations:XXXXXXXXYYYYYYYY
location2:YYYYYYYY
location3:
我在 PL/SQL 中有一个来自 SOAP 调用的结果变量,我得到的输出类型变量是 xmltype(没有写包或过程,不要得到改变它)。返回的变量类型是xmltype,想看看有没有结果。我无法理解 PL/SQL.
中 XML 周围的文档账号会一直存在,我看的是位置有没有返回。或者不止一个被退回(这会很糟糕,但我应该检查一下)。
结果看起来像
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:Action>http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule//CustomerAccountService/findCustomerAccountResponse</wsa:Action>
<wsa:MessageID>urn:uuid:7dd64ecf-676f-4667-a761-dc7603e99929</wsa:MessageID>
</env:Header>
<env:Body>
<ns0:findCustomerAccountResponse xmlns:ns0="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule/types/">
<ns0:result xsi:type="ns2:CustomerAccountResult" xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/" xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns4="http://xmlns.oracle.com/apps/cdm/foundation/parties/partyService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns9="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccount/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:Message>
<tns:code>25089</tns:code>
<tns:message>JBO-25089: Too many matching records found. Specify additional criteria to limit the number of records.</tns:message>
<tns:severity>SEVERITY_WARNING</tns:severity>
</ns1:Message>
<ns2:Value>
<ns2:AccountNumber>XXXXX</ns2:AccountNumber>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/">
<ns2:CustomerAccountSiteUse xmlns:ns6="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSiteUse/">
<ns2:Location>XXXXXXXX</ns2:Location>
</ns2:CustomerAccountSiteUse>
</ns2:CustomerAccountSite>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
</ns2:Value>
</ns0:result>
</ns0:findCustomerAccountResponse>
</env:Body>
</env:Envelope>
我觉得像
IF DBMS_LOB.INSTR(xml_response.getClobVal(), 'Location>XXXXXX<') > 0 THEN
val_returned := TRUE;
END IF;
会起作用,但我认为这可能是一种糟糕的方法?我一直在尝试阅读文档,但他们都提到从 table 等中执行 selects,而我没有 table。我可以在这些东西上使用 xml 表达式而不引用 table 吗?我必须 select 来自 dual 还是什么?
是的,Oracle 中的 XPath 并不漂亮,尤其是在涉及名称空间的情况下。我不擅长,但也许这会让你朝着正确的方向开始:
DECLARE
accountnumber VARCHAR2(100);
location VARCHAR2(100);
x XMLType := XMLType('
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:Action>http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule//CustomerAccountService/findCustomerAccountResponse</wsa:Action>
<wsa:MessageID>urn:uuid:7dd64ecf-676f-4667-a761-dc7603e99929</wsa:MessageID>
</env:Header>
<env:Body>
<ns0:findCustomerAccountResponse xmlns:ns0="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/applicationModule/types/">
<ns0:result xsi:type="ns2:CustomerAccountResult" xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/" xmlns:ns1="http://xmlns.oracle.com/adf/svc/types/" xmlns:ns4="http://xmlns.oracle.com/apps/cdm/foundation/parties/partyService/" xmlns:tns="http://xmlns.oracle.com/adf/svc/errors/" xmlns:ns9="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccount/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:Message>
<tns:code>25089</tns:code>
<tns:message>JBO-25089: Too many matching records found. Specify additional criteria to limit the number of records.</tns:message>
<tns:severity>SEVERITY_WARNING</tns:severity>
</ns1:Message>
<ns2:Value>
<ns2:AccountNumber>XXXXX</ns2:AccountNumber>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/">
<ns2:CustomerAccountSiteUse xmlns:ns6="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSiteUse/">
<ns2:Location>XXXXXXXX</ns2:Location>
<ns2:Location>YYYYYYYY</ns2:Location>
</ns2:CustomerAccountSiteUse>
</ns2:CustomerAccountSite>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
<ns2:CustomerAccountSite xmlns:ns7="http://xmlns.oracle.com/apps/cdm/foundation/parties/flex/custAccountSite/"/>
</ns2:Value>
</ns0:result>
</ns0:findCustomerAccountResponse>
</env:Body>
</env:Envelope>
');
BEGIN
SELECT EXTRACT(x, '//ns2:AccountNumber/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO accountnumber FROM DUAL;
dbms_output.put_line('accountnumber:'||accountnumber);
SELECT EXTRACT(x, '//ns2:Location/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO location FROM DUAL;
dbms_output.put_line('locations:'||location);
SELECT EXTRACT(x, '//ns2:Location[2]/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO location FROM DUAL;
dbms_output.put_line('location2:'||location);
SELECT EXTRACT(x, '//ns2:Location[3]/text()', 'xmlns:ns2="http://xmlns.oracle.com/apps/cdm/foundation/parties/customerAccountService/"').getStringVal()
INTO location FROM DUAL;
dbms_output.put_line('location3:'||location);
END;
/
这将输出
accountnumber:XXXXX
locations:XXXXXXXXYYYYYYYY
location2:YYYYYYYY
location3: