Reputation: 81
I am using XMLElement
and XMLAgg
functions in Oracle 11g to generate an XML String. This XML String this then sent to another system for parsing. I want to append the following text to the result of my XML.
The problem is, if I append the text as is, the SQL Statement returns the following -
<ZAVACOR_RESULTS>
<TEST>
<BATCH>
<BATCH_OBJECTS><ORDER_NUM> 0 </ORDER_NUM></BATCH_OBJECTS>
</BATCH>
</TEST>
</ZAVACOR_RESULTS>
I want the result to look like this -
<ZAVACOR_RESULTS>
<TEST>
<BATCH>
<BATCH_OBJECTS><ORDER_NUM>0</ORDER_NUM></BATCH_OBJECTS>
</BATCH>
</TEST>
</ZAVACOR_RESULTS>
This is my query. Any help would be much appreciated:
SELECT
XMLElement("ZAVACOR_RESULTS",
XMLAgg(
XMLElement("TEST",
XMLElement("BATCH", (case when t.batch is NULL then '<BATCH_OBJECTS> <ORDER_NUM> 0 </ORDER_NUM></BATCH_OBJECTS>' else t.batch end)),
(SELECT
XMLAgg(
XMLElement("BATCH_OBJECTS",
XMLElement("ORDER_NUMBER", (case when bo.ORDER_NUMBER is NULL then 0 else bo.ORDER_NUMBER end))
)
)
FROM BATCH_OBJECTS bo WHERE t.SAMPLE_NUMBER = bo.OBJECT_ID and
t.SAMPLE_NUMBER = 705000088556 and t.TEST_NUMBER = 4537048
)
)
)
).getClobVal() as XML
FROM TEST T WHERE t.SAMPLE_NUMBER = 705000088556 and t.test_number = 4537048;
Data Relationships:
TEST.TEST_NUMBER ---Number, Primary Key
TEST.BATCH --- Varchar2, Can be NULL
TEST.SAMPLE_NUMBER --- Number
BATCH_OBJECTS.BATCH --- Varchar2, Part of Composite Key
BATCH_OBJECTS.ORDER_NUMBER --- Number, Part of Composite Key
Upvotes: 0
Views: 1353
Reputation: 191275
You need turn your fixed string into its own XML object. You haven't shown the table structures. If test.batch
is a varchar2
(rather than an XMLType
) you can convert the result of your case:
SELECT
XMLElement("ZAVACOR_RESULTS",
XMLAgg(
XMLElement("TEST",
XMLElement("BATCH", xmltype(case when t.batch is NULL then '<BATCH_OBJECTS> <ORDER_NUM> 0 </ORDER_NUM></BATCH_OBJECTS>' else t.batch end)),
...
If test.batch
is an XMLType
then just convert the string literal:
SELECT
XMLElement("ZAVACOR_RESULTS",
XMLAgg(
XMLElement("TEST",
XMLElement("BATCH", case when t.batch is NULL then xmltype('<BATCH_OBJECTS> <ORDER_NUM> 0 </ORDER_NUM></BATCH_OBJECTS>') else t.batch end),
...
Either way these give:
XML
-------------------------------------------------------
<ZAVACOR_RESULTS><TEST><BATCH><BATCH_OBJECTS>
<ORDER_NUM> 0 </ORDER_NUM>
</BATCH_OBJECTS>
</BATCH></TEST></ZAVACOR_RESULTS>
Based on your description of what you're trying to do - which would be much easier to understand with sample data and expected output - I think what you really want is an outer join to the batch objects table, and an NVL
of the order number in case there isn't one:
SELECT XMLSerialize(CONTENT
XMLElement("ZAVACOR_RESULTS",
XMLElement("TEST",
XMLElement("BATCH",
XMLElement("BATCH_OBJECTS",
XMLAgg(
XMLElement("ORDER_NUMBER", nvl(bo.ORDER_NUMBER, 0))
)
)
)
)
) INDENT SIZE = 2
) as XML
FROM TEST T
LEFT JOIN BATCH_OBJECTS bo ON bo.BATCH = t.BATCH
WHERE t.SAMPLE_NUMBER = 705000088556
AND t.test_number = 4537048;
With XMLSerialise
just to display neatly; to pass to another application you can stick with getClobVal
:
<ZAVACOR_RESULTS>
<TEST>
<BATCH>
<BATCH_OBJECTS>
<ORDER_NUMBER>0</ORDER_NUMBER>
</BATCH_OBJECTS>
</BATCH>
</TEST>
</ZAVACOR_RESULTS>
For a test with batch_objects
records that gives:
<ZAVACOR_RESULTS>
<TEST>
<BATCH>
<BATCH_OBJECTS>
<ORDER_NUMBER>12345</ORDER_NUMBER>
<ORDER_NUMBER>23456</ORDER_NUMBER>
</BATCH_OBJECTS>
</BATCH>
</TEST>
</ZAVACOR_RESULTS>
If you want to combine multiple tests into one XML document you can have another level of XMLAgg
:
SELECT XMLSerialize(CONTENT
XMLElement("ZAVACOR_RESULTS",
XMLAgg(
XMLElement("TEST", XMLAttributes(t.TEST_NUMBER),
XMLElement("BATCH", XMLAttributes(t.BATCH),
XMLElement("BATCH_OBJECTS",
XMLAgg(
XMLElement("ORDER_NUMBER", nvl(bo.ORDER_NUMBER, 0))
)
)
)
)
)
) INDENT SIZE = 2
) as XML
FROM TEST T
LEFT JOIN BATCH_OBJECTS bo ON bo.BATCH = t.BATCH
GROUP BY t.TEST_NUMBER, t.BATCH;
I've included some attributes to distinguish the source rows:
<ZAVACOR_RESULTS>
<TEST TEST_NUMBER="4537048">
<BATCH>
<BATCH_OBJECTS>
<ORDER_NUMBER>0</ORDER_NUMBER>
</BATCH_OBJECTS>
</BATCH>
</TEST>
<TEST TEST_NUMBER="4537049">
<BATCH BATCH="BATCH_1">
<BATCH_OBJECTS>
<ORDER_NUMBER>12345</ORDER_NUMBER>
<ORDER_NUMBER>23456</ORDER_NUMBER>
</BATCH_OBJECTS>
</BATCH>
</TEST>
</ZAVACOR_RESULTS>
Upvotes: 1