XML Section in Oracle fulltext search - oracle

Could anyone advise on how to use data sections for xml section groups? Here is a quick sample:
CREATE TABLE books(
id number,
val clob
);
insert into books(id, val) VALUES(1, q'#
<book>
<references>
<ref name="isbn10">0123456789</ref>
<ref name="isbn13">0123456789123</ref>
</references>
<titles>
<title language="english">
The Lord of the rings
</title>
<title language="spanish">
El SeƱor de los Anillos
</title>
<title language="german">
Der Herr der Ringe
</title>
</titles>
</book>
#');
insert into books(id, val) VALUES(2, q'#
<book>
<references>
<ref name="isbn10">9876543210</ref>
<ref name="isbn13">3219876543321</ref>
</references>
<titles>
<title language="english">
Harry Potter and the Order of the Phoenix
</title>
<title language="italian">
Harry Potter e l'ordine della fenice
</title>
<title language="dutch">
Harry Potter en de Orde van de Feniks
</title>
</titles>
</book>
#');
COMMIT;
Since it's XML content, I would like to use the XML SECTION GROUP and create the sections like this:
BEGIN
ctx_ddl.create_section_group ('books_xml_sg', 'XML_SECTION_GROUP');
END;
/
BEGIN
ctx_ddl.add_field_section('books_xml_sg', 'reference', 'book/references/ref/name', true);
END;
/
BEGIN
ctx_ddl.add_attr_section('books_xml_sg', 'language', 'book/titles/title#language');
END;
/
And I create my index like this:
CREATE INDEX books_idx on books (val) indextype is ctxsys.context
PARAMETERS
('DATASTORE CTXSYS.DIRECT_DATASTORE
SECTION GROUP books_xml_sg
MEMORY 5M
'
);
When I do a SELECT, it works:
SELECT id, score(99)
FROM books
WHERE contains(val, 'harry', 99) > 1
ORDER BY score(99) DESC;
But, when I take the example from this link:
set long 500000
set pagesize 0
variable displayrs clob;
declare
rs clob;
begin
ctx_query.result_set('books_idx', 'harry',
'<ctx_result_set_descriptor>
<count/>
<group sdata="reference" topn="5" sortby="count" order="desc">
<count exact="true"/>
</group>
<group sdata="language" topn="3" sortby="value" order="asc">
<count exact="true"/>
</group>
</ctx_result_set_descriptor>',
rs);
/* Pretty-print the result set (rs) for display purposes.
It is not required if you are going to manipulate it in XML.*/
select xmlserialize(Document XMLType(rs) as clob indent size=2) into :displayrs from dual;
dbms_lob.freetemporary(rs);
end;
/
select :displayrs from dual;
I get the following error:
Error report -
ORA-20000: Oracle Text error:
DRG-50857: oracle error in ctx_query.result_set
ORA-20000: Oracle Text error:
DRG-13600: Syntax error in the result set descriptor at group
DRG-10837: section REFERENCE does not exist
ORA-06512: at "CTXSYS.DRUE", line 186
ORA-06512: at "CTXSYS.CTX_QUERY", line 853
ORA-06512: at line 4
20000. 00000 - "%s"
*Cause: The stored procedure 'raise_application_error'
was called which causes this error to be generated.
*Action: Correct the problem as described in the error message or contact
the application administrator or DBA for more information.
Could anyone help in here and guide me on how to use sections in XML_SECTION_GROUP?
Regards,

Related

How to return Table as a row using Oracle XML DB Webservices

I am trying to expose an Oracle Table as a web service using XML DB Service.
I want to return multiple rows of table based on where condition passed in the Request of the web service.
Following -: native-oracle-xml-db-web-services-11gr1
A procedure is developed which takes PK column as input, and returns column as output. It works when return is column by column.
But when I try to return the complete row as type, it is not working.
This is working.
URL of webservice -: http://domain:8080/orawsv/TEST/GET_TEST_TAB?wsdl
create or replace PROCEDURE GET_TEST_TAB (
p_id IN test_tab.id%TYPE,
p_description OUT test_tab.description%type) AS
BEGIN
SELECT description into p_description FROM test_tab
WHERE id = p_id;
END GET_TEST_TAB;
Now I want to return the multiple rows of TEST_TAB table, without hard coding the column name.
I have modified the procedure as
CREATE OR replace PROCEDURE P_TableAsWS_XMLIN_XMLOUT (
p_in IN XMLTYPE,
p_out OUT XMLTYPE
) AS
BEGIN
-- cursor_ OUT SYS_REFCURSOR) AS
-- with data as
--(select '<a><c>1</c><c>2</c></a>' xmlval
-- from dual)
SELECT
XMLELEMENT(
"employees",XMLAGG(XMLELEMENT(
"employee",XMLFOREST(e.id AS "empno",e.description AS "ename")
) )
)
INTO p_out
FROM
test_tab e,
XMLTABLE ( '/inp/*' PASSING p_in
COLUMNS
id varchar(50) PATH '/id'
) inp
WHERE
e.id = inp.id ;
end P_TableAsWS_XMLIN_XMLOUT;
Passing Input -:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:p="http://xmlns.oracle.com/orawsv/TEST/P_TABLEASWS_XMLIN_XMLOUT">
<soapenv:Header/>
<soapenv:Body>
<p:P_TABLEASWS_XMLIN_XMLOUTInput>
<p:P_OUT-XMLTYPE-OUT/>
<p:P_IN-XMLTYPE-IN>
<inp>
<id>1</id>
<id>2</id>
</inp>
</p:P_IN-XMLTYPE-IN>
</p:P_TABLEASWS_XMLIN_XMLOUTInput>
</soapenv:Body>
</soapenv:Envelope>
Getting Output -:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<P_TABLEASWS_XMLIN_XMLOUTOutput xmlns="http://xmlns.oracle.com/orawsv/TEST/P_TABLEASWS_XMLIN_XMLOUT">
<P_OUT>
<employees>
<employee>
<empno>1</empno>
<ename>ONE</ename>
</employee>
<employee>
<empno>2</empno>
<ename>TWO</ename>
</employee>
</employees>
</P_OUT>
</P_TABLEASWS_XMLIN_XMLOUTOutput>
</soap:Body>
</soap:Envelope>
Problem is -:
a) I have manually added each column in the procedure.
If any new column is added, procedure needs to be modified
b) XMLTABLE output column type has to be hard coded.
Unable to define column as TABLE_NAME.COLUM_NAME%TYPE

Could Not Get Columns with XMLTABLE in Oracle PL/SQL

I try to get values from columns of a XML file.
I receive XML file which in my function is assigned to c_xml but for the purposes of this question is represented in the variable c_xml in the code below.
The problem is that I have not anything printed in DBMS_OUTPUT. PUT_LINE, so I could not get any values from XML file and I could not go further with my developing.
It would be great if somebody could help to understand where is the problem with extracting values from this XML. Thanks for your time :)
The code is written on Oracle PL/SQL and follows:
DECLARE
c_xml xmltype;
BEGIN
c_xml :=
xmltype
('<?xml version=''1.0'' encoding=''utf-8''?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Header/>
<env:Body>
<srvc:returnActStateByEgnResponse xmlns="http://curr_state_egn/CURR_STATE_EGNService" xmlns:srvc="http://curr_state_egn/CURR_STATE_EGNServiceService">
<srvc:result>
<consents_tblType>
<item>
<req_id>112</req_id>
<purpose_code>CC0100</purpose_code>
<consent_state>0</consent_state>
</item>
<item>
<req_id>112</req_id>
<purpose_code>CC0200</purpose_code>
<consent_state>1</consent_state>
</item>
<item>
<req_id>112</req_id>
<purpose_code>CC0300</purpose_code>
<consent_state>0</consent_state>
</item>
</consents_tblType>
</srvc:result>
</srvc:returnActStateByEgnResponse>
</env:Body>
</env:Envelope>');
FOR consents_tblTypes IN
( SELECT
p_req_id
, p_purpose_code
, p_consent_state
FROM xmltable(
XMLNamespaces(
'http://schemas.xmlsoap.org/soap/envelope/' AS "env"
--, 'http://www.w3.org/2001/XMLSchema-instance' AS "xsi"
, 'http://curr_state_egn/CURR_STATE_EGNServiceService' AS "srvc"
),
'/env:Envelope/env:Body/srvc:returnActStateByEgnResponse/srvc:result/consents_tblType/item'
PASSING c_xml
COLUMNS
p_req_id NUMBER PATH 'req_id' --/text()
, p_purpose_code VARCHAR2(20) PATH 'purpose_code' --/text()
, p_consent_state NUMBER PATH 'consent_state' --/text()
)
)
LOOP
DBMS_OUTPUT.put_line('p_req_id = ' || to_char(consents_tblTypes.p_req_id)) ;
DBMS_OUTPUT.put_line('p_purpose_code = ' || consents_tblTypes.p_purpose_code) ;
DBMS_OUTPUT.put_line('p_consent_state = ' || to_char(consents_tblTypes.p_consent_state)) ;
END LOOP;
end;
Default namespace has to be included in the declaration.
XMLNamespaces('http://schemas.xmlsoap.org/soap/envelope/' AS "env"
, 'http://curr_state_egn/CURR_STATE_EGNServiceService' AS "srvc"
, default 'http://curr_state_egn/CURR_STATE_EGNService')
This statment xmlns="http://curr_state_egn/CURR_STATE_EGNService" changes defult namespaces.

Oracle stored procedure challenges

I'm doing my transition from T-SQL TO PL/SQL, in my first attempt I'm trying to create a stored procedure (PL/SQL) to load data into a table, but I'm getting an error:
PL/SQL: SQL Statement ignored
ORA-06550: line 29, column 4:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
Code:
declare
v_str VARCHAR2(32767) := '<ns0:ConnCustomerOrgServiceCreateRequest xmlns:ns0="http://tempuri.org" xmlns:ns6="http://schemas.microsoft.com/dynamics/2008/01/documents/ConnItemSvc" xmlns:ns4="http://schemas.microsoft.com/dynamics/2011/02/documents/DocumentPaging" xmlns:ns7="http://schemas.microsoft.com/dynamics/2011/02/documents/EntityKeyPage" xmlns:ns5="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKey" xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/sharedtypes" xmlns:ns3="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria" xmlns:ns8="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKeyList" xmlns:ns2="http://schemas.microsoft.com/dynamics/2008/01/documents/ConnCustomerOrg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns2:ConnCustomerOrg>
<ns2:CustTable class="entity">
<ns2:AccountNum xsi:nil="true" />
<ns2:CreditMax>0</ns2:CreditMax>
<ns2:CustGroup>10</ns2:CustGroup>
<ns2:Organization class="entity">
<ns2:NumberOfEmployees xsi:nil="true" />
<ns2:OrganizationName class="entity">
<ns2:Name>PRUEBA</ns2:Name>
</ns2:OrganizationName>
</ns2:Organization>
</ns2:CustTable>
</ns2:ConnCustomerOrg>
</ns0:ConnCustomerOrgServiceCreateRequest>
';
v_xml XMLTYPE := XMLTYPE(v_str);
begin
select x.AccountNum, x.CreditMax
from t
,XMLTABLE('/ConnCustomerOrgServiceCreateRequest/ConnCustomerOrg/CustTable'
PASSING t.xml
COLUMNS AccountNum NUMBER PATH '/CustTable/AccountNum'
,CreditMax NUMBER PATH '/REC/CreditMax'
) x
end;
You must have an INTO clause when you are using a SELECT statement in a PL/SQL. INTO clause lets you store the values in a declared variable/s so you can access them inside the block whenever you want. Try this:
declare
v_str VARCHAR2(32767) := '<ns0:ConnCustomerOrgServiceCreateRequest xmlns:ns0="http://tempuri.org" xmlns:ns6="http://schemas.microsoft.com/dynamics/2008/01/documents/ConnItemSvc" xmlns:ns4="http://schemas.microsoft.com/dynamics/2011/02/documents/DocumentPaging" xmlns:ns7="http://schemas.microsoft.com/dynamics/2011/02/documents/EntityKeyPage" xmlns:ns5="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKey" xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/sharedtypes" xmlns:ns3="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria" xmlns:ns8="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKeyList" xmlns:ns2="http://schemas.microsoft.com/dynamics/2008/01/documents/ConnCustomerOrg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns2:ConnCustomerOrg>
<ns2:CustTable class="entity">
<ns2:AccountNum xsi:nil="true" />
<ns2:CreditMax>0</ns2:CreditMax>
<ns2:CustGroup>10</ns2:CustGroup>
<ns2:Organization class="entity">
<ns2:NumberOfEmployees xsi:nil="true" />
<ns2:OrganizationName class="entity">
<ns2:Name>PRUEBA</ns2:Name>
</ns2:OrganizationName>
</ns2:Organization>
</ns2:CustTable>
</ns2:ConnCustomerOrg>
</ns0:ConnCustomerOrgServiceCreateRequest>
';
v_xml XMLTYPE := XMLTYPE(v_str);
v_accountnum VARCHAR2(2000);
v_creditmax VARCHAR2(2000);--i just assumed their datatypes since i cannot use %TYPE in here because i dont know what table accountnum and creditmax came from
BEGIN
SELECT x.AccountNum, x.CreditMax
INTO v_accountnum, v_creditmax
FROM t
,XMLTABLE('/ConnCustomerOrgServiceCreateRequest/ConnCustomerOrg/CustTable'
PASSING t.xml
COLUMNS AccountNum NUMBER PATH '/CustTable/AccountNum'
,CreditMax NUMBER PATH '/REC/CreditMax'
) x;
END;
Hope this helps.
You are missing a semicolon ; after your select statement. Every statement must be terminated with a ;.
declare
v_str VARCHAR2(32767) := '<ns0:ConnCustomerOrgServiceCreateRequest xmlns:ns0="http://tempuri.org" xmlns:ns6="http://schemas.microsoft.com/dynamics/2008/01/documents/ConnItemSvc" xmlns:ns4="http://schemas.microsoft.com/dynamics/2011/02/documents/DocumentPaging" xmlns:ns7="http://schemas.microsoft.com/dynamics/2011/02/documents/EntityKeyPage" xmlns:ns5="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKey" xmlns:ns1="http://schemas.microsoft.com/dynamics/2008/01/sharedtypes" xmlns:ns3="http://schemas.microsoft.com/dynamics/2006/02/documents/QueryCriteria" xmlns:ns8="http://schemas.microsoft.com/dynamics/2006/02/documents/EntityKeyList" xmlns:ns2="http://schemas.microsoft.com/dynamics/2008/01/documents/ConnCustomerOrg" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns2:ConnCustomerOrg>
<ns2:CustTable class="entity">
<ns2:AccountNum xsi:nil="true" />
<ns2:CreditMax>0</ns2:CreditMax>
<ns2:CustGroup>10</ns2:CustGroup>
<ns2:Organization class="entity">
<ns2:NumberOfEmployees xsi:nil="true" />
<ns2:OrganizationName class="entity">
<ns2:Name>PRUEBA</ns2:Name>
</ns2:OrganizationName>
</ns2:Organization>
</ns2:CustTable>
</ns2:ConnCustomerOrg>
</ns0:ConnCustomerOrgServiceCreateRequest>
';
v_xml XMLTYPE := XMLTYPE(v_str);
begin
select x.AccountNum, x.CreditMax
from t
,XMLTABLE('/ConnCustomerOrgServiceCreateRequest/ConnCustomerOrg/CustTable'
PASSING t.xml
COLUMNS AccountNum NUMBER PATH '/CustTable/AccountNum'
,CreditMax NUMBER PATH '/REC/CreditMax'
) x;
end;

EF5 how to access SYS_REFCURSOR in Oracle stored procedure

I have an Oracle Stored Procedure that has a return cursor that I would like to access using EF 5. I have read multiple question from the site but still can not get it to work.
This is my oracle stored procedure:
CREATE OR REPLACE PROCEDURE GETINFO
(
"StoreId" IN varchar2 , OUT_RESULT OUT SYS_REFCURSOR
)
IS
sqlstmt VARCHAR2(2000);
BEGIN
sqlstmt := 'SELECT v."StoreId", v."ProductCategory" "Product", v."ProductId"
FROM SUPERMARKET v WHERE v."StoreId"='||"StoreId";
OPEN Out_Result FOR sqlStmt;
END GETINFO;
According to Oracle documentation, to access SYS_REFCURSOR, I have to explicitly declare it in my App.config, which I did:
<oracle.dataaccess.client>
<settings>
<oracle.manageddataaccess.client>
<version number="*">
<StoredProcedure schema="MYSCHEMA" name="GETINFO">
<refCursor name="OUT_RESULT">
<bindInfo mode="Output" />
<metadata columnOrdinal="0" columnName="StoreId" providerType="NUMBER" />
<metadata columnOrdinal="1" columnName="Product" providerType="Varchar2" />
<metadata columnOrdinal="2" columnName="ProductId" providerType="Varchar2" />
</refCursor>
</StoredProcedure>
</version>
</oracle.manageddataaccess.client>
</settings>
</oracle.dataaccess.client>
There may be other pieces hidden from Oracle documentation regarding meta data that I may have to include in the App.Config. As a result, I am still not able to access my specific SYS_REFCURSOR because when I clicked on Get Column Information, I got nothing and there was nothing in the complex combo box. According to Oracle, I should have to structure of the SYS_REFCURSOR to refer to.
My Entity Framework is 5.0, I use VS 2012.
What else do I need to include in the meta data?
My underlying SUPERMARKET table structure is:
Name Null Type
--------------- ---- ------------
StoreId NUMBER
ProductCategory VARCHAR2(20)
ProductId VARCHAR2(20)

how to set the empty tag in generating xml from oracle table

SET PAGES 0;
SET LINE 1000;
SET LONG 9999999;
SPOOL C:\pensionnew.xml;
col foo format a60000
SELECT DBMS_XMLGEN.GETXML('SELECT * FROM DATAAG')foo FROM DUAL;
SPOOL OFF;
i use this code for generating xml.. the answer is:suppose the the column not have value means the tag wont came . i need empty tag for that for that
use the API for it, dont use the quick fire getxml(string) version.
eg:
SQL> variable xml clob;
SQL> declare
2 ctx number;
3 begin
4 dbms_lob.createtemporary(:xml, true, dbms_lob.call);
5 ctx := dbms_xmlgen.newcontext('select * from foo');
6 dbms_xmlgen.setnullhandling(ctx, dbms_xmlgen.EMPTY_TAG);
7 dbms_xmlgen.getxml(ctx, :xml);
8 dbms_xmlgen.closecontext(ctx);
9 end;
10 /
PL/SQL procedure successfully completed.
SQL> print xml
XML
--------------------------------------------------------------------------------
<?xml version="1.0"?>
<ROWSET>
<ROW>
<ID>1</ID>
<A>a</A>
</ROW>
<ROW>
<ID>2</ID>
<A/>
</ROW>
</ROWSET>

Resources