Oracle multiple XMLAgg - oracle10g

I am building a sql query with Oracle 10g,
And would like to get sql output with below xml format:
<Users>
<User>
<USRID>1234</USRID>
<USERNAME>ABCD</USERNAME>
<ROLES>
<ROLE>
<ROLEID>1</ROLEID>
<ROLENAME>GlobalAdministrator</ROLENAME>
<ISDEFAULTROLE>1</ISDEFAULTROLE>
</ROLE>
<ROLE>
<ROLEID>2</ROLEID>
<ROLENAME>Administrator</ROLENAME>
<ISDEFAULTROLE>0</ISDEFAULTROLE>
</ROLE>
</ROLES>
</User>
<User>
<USRID>2312</USRID>
<USERNAME>XUX</USERNAME>
<ROLES>
<ROLE>
<ROLEID>3</ROLEID>
<ROLENAME>AccountManager</ROLENAME>
<ISDEFAULTROLE>1</ISDEFAULTROLE>
</ROLE>
<ROLE>
<ROLEID>5</ROLEID>
<ROLENAME>Approver</ROLENAME>
<ISDEFAULTROLE>0</ISDEFAULTROLE>
</ROLE>
</ROLES>
</User>
</Users>
Sql I just build:
SELECT XMLElement("Users",
XMLAgg(XMLElement("User",
XMLElement("USRID",u.USRID) ,
XMLElement("USERNAME",u.USERNAME) ,
XMLElement("Roles",
SELECT xmlagg(XMLElement("Role",
XMLElement("ROLEID",ur.ROLEID),
XMLElement("ROLENAME",r.NAME),
xmlelement("ISDEFAULTROLE",ur.PRIMARY))
FROM USERROLE ur,role r WHERE u.USRID = ur.USRID AND r.ROLEID = ur.ROLEID))))).getClobVal()
FROM usr u
But its giving below error:
ORA-00936: missing expression
00936. 00000 - "missing expression"
*Cause:
*Action:
Error at Line: 26 Column: 1
How can I do this?

I have figured it out:
SELECT XMLElement("Users",
XMLAgg(XMLElement("User"
,XMLElement("USRID",u.USRID)
,XMLElement("USERNAME",u.USERNAME)
,xmlElement("Roles",
(
select xmlAgg(xmlElement("Role"
,XMLElement("ROLEID",ur.ROLEID)
,XMLElement("ROLENAME",r.NAME)
,xmlelement("ISDEFAULTROLE",ur.PRIMARY)))
from USERROLE ur,role r where u.USRID = ur.USRID and r.ROLEID = ur.ROLEID)
)))).getClobVal()
from usr u

Related

SQL Server 2016 XML Shredding

Have been trying to figure this out for a while without success, read like 10 posts and some other examples and the MS help, not resonating, need to shred some xml data with the following format:
<ncf_report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://cp.com/rules/client">
<admin>
<quoteback name="abcd">ABCD A</quoteback>
<product_group>Abcd ABcd Abcd</product_group>
<pnc_account>123456</pnc_account>
<pnc_account_name>ABC</pnc_account_name>
<product_reference>123456789</product_reference>
<report_type>ABCDE</report_type>
<status>ABCDE</status>
<ownership>ABCD</ownership>
<report_code>1234</report_code>
<report_description>Abcde/report_description>
<purpose>ABCDEFGH</purpose>
<date_request_ordered>05/05/2020</date_request_ordered>
<date_request_received>05/05/2020</date_request_received>
<date_request_completed>05/05/2020</date_request_completed>
<time_report_processed>1028</time_report_processed>
<multiple_scores_ordered>false</multiple_scores_ordered>
<vendor name="Abcd" address="Abcd" />
<report>
<sequence>0000000001</sequence>
<count>0000000001</count>
</report>
</admin>
<report>
<alerts_scoring>
<scoring>
<score status="Abcd">
<model_label>ABCD</model_label>
<score>123</score>
<rating_state>AB</rating_state>
<classification> ABCD </classification>
<reason_codes>
<code>12</code>
<description>ABCD</description>
</reason_codes>
<reason_codes>
<code>12</code>
<description>ABCD</description>
</reason_codes>
<reason_codes>
<code>12</code>
<description>ABCD ABCD ABCD</description>
</reason_codes>
<reason_codes>
<code>12</code>
<description>ABCD ABCD ABCD</description>
</reason_codes>
</score>
</scoring>
<general>ABCD ABCD ABCD ORIGINAL REPORT DATE: 12/12/2000</general>
<general>ABCD ABCD ABCD</general>
<general> ABCD ABCD ABCD</general>
<general narrativeCode="Abcd Abcd">ABCD ABCD ABCD</general>
<general narrativeCode=" Abcd Abcd">ABCD ABCD ABCD</general>
<general narrativeCode=" Abcd Abcd">ABCD ABCD ABCD</general>
</alerts_scoring>
<vendor_dataset>
<subjects>
<subject type="Abcd" relationship_to_data="Abcd">
<name type="Abcd">
<first>XXXX</first>
<middle>X</middle>
<last>XXXX</last>
</name>
<birth_date>01/01/1900</birth_date>
<ssn>999999999</ssn>
<address type="Abcd" ref="1" />
<address type="Abcd" ref="2" />
<address type="Abcd" ref="3" />
</subject>
</subjects>
<addresses>
<address id="1">
<street1>ABCD</street1>
<city>ABCD</city>
<state>AB</state>
<postalcode>12345</postalcode>
<zip4>1234</zip4>
<date_first_at_address>01/02/1900</date_first_at_address>
<date_last_at_address>01/02/1900</date_last_at_address>
</address>
<address id="2">
<house>123</house>
<street1>ABCDE</street1>
<city>ABCDE</city>
<state>AB</state>
<postalcode>12345</postalcode>
<zip4>1234</zip4>
<date_first_at_address>00/00/1900</date_first_at_address>
<date_last_at_address>00/00/1900</date_last_at_address>
</address>
<address id="3">
<street1>ABCDE</street1>
<city>ABCDE</city>
<state>AB</state>
<postalcode>12345</postalcode>
<zip4>1234</zip4>
<date_first_at_address>00/00/1900</date_first_at_address>
<date_last_at_address>00/00/1900</date_last_at_address>
</address>
</addresses>
</vendor_dataset>
<summary>
<date_oldest_trade>00/00/1900</date_oldest_trade>
<date_latest_trade>00/00/1900</date_latest_trade>
<date_latest_activity>00/00/1900</date_latest_activity>
<includes_bankruptcies flag="true" date="02/02/2009" />
<includes_other_records public_records="false" collection="true" consumer_statement="false" />
<credit_range high="123456" low="1234" number_trade_lines="12" />
**<account_status_counters>
<account type="current" description="Pays Account as Agreed" status="1">12</account>
<account type="current" description="Status Not Known" status=" ">7</account>
<account type="former" description="Pays/Paid 30-60 Days or Max 2 Payments Past Due" status="2">5</account>
<account type="former" description="Pays/Paid 60-90 Days or Max 3 Payments Past Due" status="3">4</account>
<account type="former" description="Bad Debt" status="9">6</account>
</account_status_counters>**
I currently going down the path of trying to use the xml procedure but I could not get to the finish line with openxml as well. Trying to extract data in highlighted at bottom of xml
EXEC sp_xml_preparedocument #hdoc OUTPUT, #CreditScoreXML
SELECT * FROM OPENXML(#hdoc, '/<ncf_report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://cp.com/rules/client">/admin/summary/account_status_counters')
WITH
(
[Ref_Number] VARCHAR(10) 'product_reference',
[current_account_type] VARCHAR(10) './account/#type',
[current_account_type_description] VARCHAR(50) './account/#description',
[current_account_type_description] VARCHAR(1) './account/#status'
You can define the namespace for your XML using WITH XMLNAMESPACES statement, then you can extract the values you need with .value().
I don't understand exactly the information you are trying to extract, but this should put you on the right track (I only put the first row of your xml to save space, you should put the entire XML fragment in the #xml variable):
declare #xml xml set #xml='
<ncf_report xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://cp.com/rules/client">
...
'
;WITH XMLNAMESPACES ('http://cp.com/rules/client' as ns1)
select
#xml.value('(ns1:ncf_report/ns1:admin/ns1:product_reference)[1]', 'varchar(10)') as Ref_Number
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status ="1"]/#description)[1]', 'varchar(50)') as CurrentDescription
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status ="1"])[1]', 'int') as CurrentStatus
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status =" "]/#description)[1]', 'varchar(50)') as CurrentDescription_2
,#xml.value('(ns1:ncf_report/ns1:report/ns1:summary/ns1:account_status_counters/ns1:account[#type="current" and #status =" "])[1]', 'int') as CurrentStatus_2
This sample query would extract:

LIMIT in PostgresQL

I have query written in Oracle in MyBatis Mapper xml file like below:
<select id="getUserList" resultMap="userListResult" parameterType="org.user.UserNumber>
select * from user
WHERE (1=1)
<if test="num != null">AND rownum <= #{num}</if>
</select>
I need to make this Postgres Compliant. So, converted as below:
<select id="getUserList" resultMap="userListResult" parameterType="org.user.UserNumber>
select * from user
WHERE (1=1)
<if test="num != null">AND LIMIT #{num}</if>
</select>
But it is not working and throwing exception:
PSQLException: ERROR: syntax error at or near \"LIMIT\"\n
Can anyone help me please how to replace rownum here in Postgres?

XQuery modify with variable

I have the follow XML
<root>
<business name="LM" id="1" total_pes="0">
</business>
<business name="KO" id="354" total_pes="0">
</business>
<business name="TUI" id="889" total_pes="0">
</business>
</root>
I want to update the total_pes attribute with a record count of other table tbl_logs:
id | log
1 | A
1 | A
1 | A
354 | A
354 | A
889 | A
My output XML would be this:
<root>
<business name="LM" id="1" total_pes="3">
</business>
<business name="KO" id="354" total_pes="2">
</business>
<business name="TUI" id="889" total_pes="1">
</business>
</root>
This is what I already done:
DECLARE #total_pes_new int
DECLARE #ID INT
SET #ID = (SELECT TOP 1 ID FROM #IDS)
WHILE #ID IS NOT NULL
BEGIN
set #total_pes_new = ( SELECT COUNT(A.PES) FROM TBL A
WHERE A.ID = #ID)
SET #XML.modify('replace value of (/root/business[#id=sql:variable("#ID")]/#total_pes)[1] with sql:variable("#total_pes_new")')
SET #ID = (SELECT TOP 1 ID FROM #IDS WHERE ID > #ID)
END
I will have problems with this loop. Can anyone help me to do a better solution?
Tks
If your XML is in an XML database, then you also have the option of using XQuery Update, see http://www.w3.org/TR/xquery-update-10/.

Editor extensions for SQL Developer

I'm attempting to write an (editor) extension for Oracle SQL Developer. I'm having trouble finding information about it, but I've pieced the following together from the few tutorials and blog entries that I've found:
<?xml version="1.0" encoding="UTF-8"?>
<displays>
<display enable="true" objectType="SEQUENCE" style="null" type="editor">
<name><![CDATA[Details]]></name>
<query>
<sql>
<![CDATA[
SELECT 'sequence_name' AS "NAME", sequence_name AS "VALUE" FROM :NAME
UNION
SELECT 'last_value' AS "NAME", CAST(last_value AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'start_value' AS "NAME", CAST(start_value AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'increment_by' AS "NAME", CAST(increment_by AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'max_value' AS "NAME", CAST(max_value AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'min_value' AS "NAME", CAST(min_value AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'cache_value' AS "NAME", CAST(cache_value AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'log_cnt' AS "NAME", CAST(log_cnt AS text) "VALUE" FROM :NAME
UNION
SELECT 'is_cycled' AS "NAME", CAST(is_cycled AS text) AS "VALUE" FROM :NAME
UNION
SELECT 'is_called' AS "NAME", CAST(is_called AS text) AS "VALUE" FROM :NAME
]]>
</sql>
</query>
<CustomValues>
<TYPE>vertical</TYPE>
</CustomValues>
</display>
</displays>
This works, in that extra tabs do show up for sequences on Oracle db connections. However, they do not show up for Postgres db connections. For sequences to even show in pg databases in SQL Dev, I have to use a second extension script:
<?xml version="1.0" encoding="windows-1252" ?>
<navigator RESOURCE_FILE="oracle.dbtools.raptor.navigator.OracleNavigatorResource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="navigator.xsd">
<objectType connType="PostgreSQL" id="SEQUENCE" includesSyns="true" weight="100.0">
<folder>
<icon RSKEY="SEQUENCE_FOLDER_ICON"/>
<label RSKEY="Sequences"/>
<queries>
<query minversion="8">
<sql constrained="true"><![CDATA[SELECT relname, nspname FROM pg_class JOIN pg_namespace ON pg_namespace.oid = pg_class.relnamespace WHERE relkind = 'S' AND nspname = :SCHEMA]]></sql>
</query>
<columns>
<column filterable="true" id="SEQUENCENAME" sortable="true">
<colName><![CDATA[relname]]></colName>
</column>
<column filterable="true" id="NAME" sortable="true">
<colName><![CDATA[relname]]></colName>
</column>
</columns>
</queries>
</folder>
<node>
<icon RSKEY="OracleIcons.SEQUENCE"/>
</node>
</objectType>
</navigator>
Is there a way to specify that this extension only applies to Postgres sequences, and not to Oracle sequences?
The correct answer here seems to be to have a connType="PostgreSQL" attribute in the display element. This limits it to only Postgres sequences. This was trial and error, I can't find editor.xsd and it seems like Oracle doesn't make it available.

Generate XML from Table

I have a table like this:
ID Name Column1 Column2 Column3
1 ABC 202.2 1500 34000
2 IJK 104 10000 27000
I want to generate XML like this:
<doc>
<record ID="1" Name="ABC" Column1="202.2" Column2="15000" Column3="34000" />
<record ID="2" Name="IJK" Column1="104" Column2="10000" Column3="27000" />
</doc>
I have got some clue from this forum post and used this code:
CREATE TABLE #tmp (column1 VARCHAR(20), column2 VARCHAR(20), column3 VARCHAR(20))
INSERT INTO #tmp VALUES ( 'data1', 'data2', 'data3' )
INSERT INTO #tmp VALUES ( 'data11', 'data21', 'data31' )
-- FOR XML PATH with ELEMENTS will automatically unpivot the data for you
-- Then reshape your XML using nested FLWOR loops
SELECT
(
SELECT *
FROM #tmp t
FOR XML PATH, ELEMENTS, TYPE
).query('
for $e in row
return
<row>{
for $f in $e/*
return <field name="{local-name($f)}">{data($f)}</field>
}
</row>
')
I tried the following modified version:
SELECT (SELECT * FROM cte_temp t FOR XML PATH, ELEMENTS, TYPE)
.query('for $e in row return
<doc>
{
for $f in $e return <record {local-name($f)}="{data($f)}" />
}
</doc>')
But I'm getting error:
XQuery [query()]: Invalid source character 0x7b found in an identifier
near 'return'.
Why you trying to get fancy.
Select * from #tmp as record
FOR XML AUTO, root('doc')