i have a column in table which contain data like XML,i would like to get data in rows.
My table data as-
select printDataColumn from Mytable
It returns value-
<PrintData> <Line1>.MERCHANT ID: *****4005</Line1> <Line2>.CLERK ID: ADMIN</Line2> <Line3>.</Line3> <Line4>. VOID SALE</Line4> <Line5>.</Line5> <Line6>.VISA ************0006</Line6> <Line7>.ENTRY METHOD: SWIPED</Line7> <Line8>.DATE: 03/05/2019 TIME: 16:57:20</Line8> <Line9>.</Line9> <Line10>.INVOICE: 1551785225020</Line10> <Line11>.REFERENCE: 1008</Line11> <Line12>.AUTH CODE: 08354A</Line12> <Line13>.</Line13> <Line14>.AMOUNT USD$ 1.14</Line14> <Line15>. ==========</Line15> <Line16>.TOTAL USD$ 1.14</Line16> <Line17>.</Line17> <Line18>. APPROVED - THANK YOU</Line18> <Line19>.</Line19> <Line20>.I AGREE TO PAY THE ABOVE TOTAL AMOUNT</Line20> <Line21>.ACCORDING TO CARD ISSUER AGREEMENT</Line21> <Line22>.(MERCHANT AGREEMENT IF CREDIT VOUCHER)</Line22> <Line23>.</Line23> <Line24>.</Line24> <Line25>.</Line25> <Line26>.x_______________________________________</Line26> <Line27>. Merchant Signature</Line27> <Line28>.</Line28> </PrintData>
but i want to use this information in another way like that
MERCHANT ID: *****4005 CLERK ID: ADMIN SALE AMEX ***********1006 ENTRY METHOD: CHIP DATE: 03/07/2019 TIME: 14:37:23 INVOICE: 1551949638173 REFERENCE: 1005 AUTH CODE: 040749. . . . .and so on.
any help is appreciable.
Advertisement
Answer
Besides the fact, that it always is a good idea to use the appropriate type to store your data, you can use a cast on the fly to use your xml-like-data with XML methods:
DECLARE @tbl TABLE(ID INT IDENTITY,PrintData VARCHAR(4000)); INSERT INTO @tbl VALUES ('<PrintData> <Line1>.MERCHANT ID: *****4005</Line1> <Line2>.CLERK ID: ADMIN</Line2> <Line3>.</Line3> <Line4>. VOID SALE</Line4> <!-- more lines --> </PrintData>'); SELECT t.ID ,A.Casted.value(N'(/PrintData/Line1/text())[1]','nvarchar(max)') AS Line1 FROM @tbl t CROSS APPLY(SELECT CAST(t.PrintData AS XML)) A(Casted);
In this case I use CROSS APPLY
to add a column A.Casted
to the result set, which is a row-wise casted XML.
This will break, in cases of invalid XML (of course). You might try TRY_CAST
instead. This would return NULL
, but will hide data errors…
Some more background
The cast to XML is a rather expensive operation. Doing this whenever you want to read out of your data is some heavy load for your server. Furthermore, using VARCHAR
is prone to two major errors:
- If there are foreign characters you might get question marks
- If the XML is not valid, you will not see it – until you use it.
If possible, try to change the table’s design to use native XML.
And one more hint
It is a bad approach to name-number elements (same for columns). Instead of <Line1><Line2><Line3>
better use <Line nr="1"><Line nr="2"><Line nr="3">
…