i have a table which i save user's search result rows in xml format as follows :
<row id="5083" />
<row id="5085" />
<row id="5087" />
<row id="5090" />
<row id="5094" />
... (about 500,000 rows)
where each row element contains id of the result record which will be shown in result page.
now i need to select ids of one specific page for example page 2 ( 10th element to 20th element )
the first problem is how can i get that result in xquery ?
i tried to use position() function but it didn't work ...
select #results.query('for $x in (row)
where $x/position() > 10
return ($x)')
and the second prblem is how can get my result ids as sql rows instead of xmlnodelist ?
You can use the nodes() method to shred your XML and use the value() method to extract the value for attribute id.
SQL Fiddle
Query 1:
declare #results xml = '
<row id="5083" />
<row id="5085" />
<row id="5087" />
<row id="5090" />
<row id="5094" />'
select T.N.value('#id', 'int') as id
from #results.nodes('row[position() >= 2 and position() < 4]') as T(N)
Results:
| ID |
--------
| 5085 |
| 5087 |
In
for $x in (row) where $x/position() > 10 return ($x)
$x iterates over all the row children after the 10th but for each returns a sequence of length 1 with just one row element so $x/position() is always 1.
You could use
row[position() >=10 and position() < 20]
which will return elements in positions 10 to 19. If you want just the id's rather than the element nodes then
row[position() >=10 and position() < 20]/string(#id)
Related
I have a table called parts with an XMLType column called RunList_XML
The XML has several Unit tags example <Item> <Unit>420</Unit> </Item> <Item> <Unit>10</Unit> </Item> <Item> <Unit>0</Unit> </Item>
I want to query to get back a list of all parts
that have a Unit of 420
I cant seem to figure out how to get this using = 420 or = '420'
the below gives back false positives
select * from Parts P
WHERE P.RunList_XML.extract('ArrayOfItem// /Unit/text()').getStringVal() like '%420'
Try this using existsnode:
select * from Parts P
WHERE existsnode(RunList_XML, 'ArrayOfItem//Item[Unit="420"]') = 1
existsnode returns 1 if node is found and 0 if not.
I am using version PostgreSQL 8.3.12.
Table Column Name : xmltest
id data
Data Column contains XML data that looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ItemData>
<ReviewComments><?xml version="1.0" encoding="utf-8"?>
</ReviewComments>
<SmartTextData RootProtect="True">
<STI_Summary IID="d10c5cbf-f5cf-4478-9f33-4580c1930413" IR="True">
<ObjectValue />
<CP />
<SIProps ST="4" PL="False" PLS="" />
<STI_SummaryActiveProblemsField LIID="cdbd7044-ccde-11db-8cba-df0a56d89593" IID="37742a5f-7998-4715-8d43-0d7a19284d44" IR="True" RW="1">
<HD Title="Active Problems" />
<ObjectValue />
<CP>
<PosReplace />
<NegReplace />
</CP>
<SIProps ST="4" PL="False" PLS="" />
<STI_US>
<ObjectValue>
<TextValue>
<![CDATA[
]]>
</TextValue>
</ObjectValue>
<CP />
<SIProps ST="1" SS=" " PL="False" PLS="" />
</STI_US>
<STI_DxItem LIID="71194038-8ffb-488b-8af5-5f1f1a679115" IID="aaf2de4e-2f1f-409b-87b7-b7265bec37db" RW="1">
<HD Title="Coronary artery disease " />
<ObjectValue>
<Code>
<CodingSystem>ICD-9 CM</CodingSystem>
<Value>414.01</Value>
</Code>
<Code>
<CodingSystem>SWICPC</CodingSystem>
<Value>08.0.K76.CIR</Value>
</Code>
</ObjectValue>
</STI_DxItem >
</STI_Summary>
</SmartTextData>
</ItemData>
I want to spilt XML Tag IID and CODE data to respective ID Column.
Expected Output :
ID LIID Code_Value CodingSystem
1 d10c5cbf-f5cf-4478-9f33-4580c1930413 NULL
1 37742a5f-7998-4715-8d43-0d7a19284d44 NULL
1 aaf2de4e-2f1f-409b-87b7-b7265bec37db 414.01 IC CM
1 aaf2de4e-2f1f-409b-87b7-b7265bec37db 08.0.K76.CIR SWICPC
Note : I am using version PostgreSQL 8.3.12 with this some new syntax of XMLPATH not work.
Simply I want to convert XML Data to rows column structure.
Thanks for Reading this.
Looking at SO questions, I've found this:
ERROR: function unnest(integer[]) does not exist in postgresql
According to the solution of this question, you can implement unnest by your own, on a one-dimension arrays in this way:
CREATE OR REPLACE FUNCTION unnest2(anyarray)
RETURNS SETOF anyelement AS
$BODY$
SELECT $1[i] FROM generate_series(array_lower($1,1), array_upper($1,1)) i;
$BODY$ LANGUAGE sql IMMUTABLE;
This function should allow to query your data using next sentence:
SELECT xpath('/ItemData/SmartTextData/STI_Summary/STI_DxItem/#IID', data, array[array['aaa','example.com']]) as IID,
unnest2(xpath('/ItemData/SmartTextData/STI_Summary/ObjectValue/Code/CodingSystem/text()', data, array[array['aaa','example.com']])) as Code,
unnest2(xpath('/ItemData/SmartTextData/STI_Summary/ObjectValue/Code/Value/text()', data, array[array['aaa','example.com']])) as Value
from xmltest2;
Notice, I've used array[array['aaa','example.com']] as you pointed out in your comments, due your XML data has not schema.
I've tested it in rextester and it works.
+--------------------------------------+----------+--------------+
| iid | code | value |
+--------------------------------------+----------+--------------+
| aaf2de4e-2f1f-409b-87b7-b7265bec37db | ICD-9 CM | 414.01 |
+--------------------------------------+----------+--------------+
| aaf2de4e-2f1f-409b-87b7-b7265bec37db | SWICPC | 08.0.K76.CIR |
+--------------------------------------+----------+--------------+
Check it here: Rextester
I'm trying to update a XML column in a SQL Server table using the
XML.modify replace value of (XML DML)
With the below XML example, is there a way I can replace all vendorId with value 1 into another value? From the documentation in http://technet.microsoft.com/en-us/library/ms190675.aspx it looks like I need to specify the record index for that. But in my case, there would be multiple records within the xml and I would not know the order it would be in.
<LineItems>
<LineItem productId="48" invId="1573" quantity="1" id="1" vendorId="1022" price="1350.0000" cost="450.0000" discount="0" acqu="2" />
<LineItem productId="1" invId="0" quantity="1" id="2" vendorId="1" price="400" cost="0" discount="0" />
<LineItem productId="46" invId="1574" quantity="1" id="3" vendorId="1022" price="789.0000" cost="263.0000" discount="0" acqu="4" />
<LineItem productId="1" invId="0" quantity="1" id="4" vendorId="1" price="300" cost="0" discount="0" />
</LineItems>
Please advice.
Thanks!
You have to use a loop and update one value at a time.
while #XML.exist('/LineItems/LineItem[#vendorId = "1"]') = 1
set #XML.modify('replace value of (/LineItems/LineItem[#vendorId = "1"]/#vendorId)[1] with "2"' )
SQL Fiddle
A version that updates a XML column in a table would look like this.
while exists(
select * from T
where T.XMLColumn.exist('/LineItems/LineItem[#vendorId = "1"]') = 1
--and [some other condition]
)
begin
update T
set XMLColumn.modify('replace value of (/LineItems/LineItem[#vendorId = "1"]/#vendorId)[1] with "2"')
where T.XMLColumn.exist('/LineItems/LineItem[#vendorId = "1"]') = 1
--and [some other condition]
end
SQL Fiddle
If you need to replace a constant string to another one, I advise you yo use REPLACE function and perfom it on string.
DECLARE #XML XML /*your xml value*/
SELECT REPLACE(CONVERT(NVARCHAR(MAX),#XML),'vendor="1"','"vendor="2"')
In many cases it's much easier then do it in xml-style.
Generating XML from SQL server, however I want to exclude items from results that are NULL or 0 (zero). Is this possible? I've attached a sample of the SELECT statement along with some XML results.
SELECT
VehicleID AS 'VehicleID/#id',
SubModelID AS 'SubModelID/#id',
EngineID AS 'EngineID/#id',
FROM myTable
FOR XML PATH('App')
Here is a sample result:
<App>
<VehicleID id="128001" />
<SubModelID id="295" />
<EngineID id="0" />
</App>
I'd like to exclude the EngineID result (or any others) in the case where the ID=0, like the following:
<App>
<VehicleID id="128001" />
<SubModelID id="295" />
</App>
NULL values will not add a value to your XML.
To exlude 0 from the result you can use nullif(columnname, 0).
I have an xml data that looks like below.
DECLARE #XmlContent XML
SET #XmlContent =
'<Entities>
<Entity type = "5">
<item id ="1"/>
<item id ="2"/>
<item id ="2"/>
</Entity>
<Entity type = "6">
<item id ="3"/>
<item id ="4"/>
<item id ="5"/>
</Entity>
</Entities>'
I want to select data from this and insert into a table in the following format -
------------
Type Id
------------
5 1
5 2
5 2
6 3
6 4
6 5
Can some one help me to write query for this in sql server?
select
ent.value('#type', 'int') as Type,
row.value('#id', 'int') as ID
from
#XmlContent.nodes('/Entities/Entity') foo(ent)
cross apply ent.nodes('item') bar(row)