Querying by a value in XML in SQL Server 2005 - sql

Let's say I have a column in a table where the datatype is XML. I have a specific value I want query for in an xml tag that is unique(no repeating) in the XML. How do I do this?
Something like:
select * from MyTable
where XMLColumn.TagImLookingAt.Value = #QueryValue

Use:
WHERE xmlcolumn.value('(/path/to/tag)[1]', 'int') = #QueryValue
Change the data type to whatever is appropriate.
For more info, see the documentation - specifically the methods available when dealing with the XML data type...

Related

extract value from xml data column oracle sql

From the database there is a column which contains xml data in the format like:
<old_template_code> something </old_template_code><old_template_name> new
code</old_template_name><new_template_code>BEVA24M</new_template_code>
How can I extract the values from the xml and make a column for each of the different xml values? For example I would like to do something like:
select EXTRACTVALUE(table.column, table.column)
but the latter doesn't work for me.

FOR XML AUTO and sql server 2005

SELECT * FROM emp FOR XML AUTO , ROOT ('Employees') , ELEMENTS
this query return value in xml format but total xml is showing in one column and column name is showing dynamically. if i want that i will specify the column name like data etc. so xml value will show as single row & column but header or output column name will be "DATA"
is it possible if yes the please show me the way.thanks
You need to check out the new FOR XML PATH feature in SQL Server 2005 and up - read all about it in SQL Server Books Online.
Basically, with FOR XML PATH, you can define the shape of your XML very easily, e.g.
SELECT
EmployeeID AS '#EmployeeID',
FirstName,
LastName
FROM dbo.Employees
FOR XML PATH('Employee'), ROOT('AllEmployees')
will generate XML something like:
<AllEmployees>
<Employee EmployeeID="12345">
<FirstName>John</FirstName>
<LastName>Doe</LastName>
</Employee>
</AllEmployees>
FOR XML PATH is very flexible and allows you to do a lot of things quite easily and intuitively.

XML XQUERY Problem with NTEXT data type

I want to use XQuery on a column of data type NTEXT (I have no choice!). I have tried converting the column to XML using CONVERT but it gives the error:
Incorrect syntax near the keyword 'CONVERT'.
Here's the query
SELECT
y.item.value('#UserID', 'varchar(50)') AS UnitID,
y.item.value('#ListingID', 'varchar(100)') AS #ListingID
FROM
dbo.KB_XMod_Modules
CROSS APPLY
CONVERT(xml, instancedata).nodes('//instance') AS y(item)
(instancedata is my column)
Can anyone think of a work around for this ?
Thanks
It seems that neither CONVERT nor CAST(... AS XML) work.
The XQuery stuff really only works on XML columns - sorry.
However: maybe there's an escape route :-)
You could do one of two things:
add a persisted computed column of type XML to your table and party on that new column
or - if you can't change the table structure -
create a view over that table and include a XML-casted column
So for solution #1 you'd do:
ALTER TABLE KB_XMod_Modules
ADD XmlCol AS CAST(instancedata AS XML) PERSISTED
and for solution #2, you'd use:
CREATE VIEW KBwithXML AS
SELECT instancedata, CAST(instancedata AS XML) 'XmlCol'
FROM KB_XMod_Modules
In both cases, you now have a XmlCol of type XML available, which you can query with XQuery to your heart's delight!

Use a LIKE statement on SQL Server XML Datatype

If you have a varchar field you can easily do SELECT * FROM TABLE WHERE ColumnA LIKE '%Test%' to see if that column contains a certain string.
How do you do that for XML Type?
I have the following which returns only rows that have a 'Text' node but I need to search within that node
select * from WebPageContent where data.exist('/PageContent/Text') = 1
Yet another option is to cast the XML as nvarchar, and then search for the given string as if the XML vas a nvarchar field.
SELECT *
FROM Table
WHERE CAST(Column as nvarchar(max)) LIKE '%TEST%'
I love this solution as it is clean, easy to remember, hard to mess up, and can be used as a part of a where clause.
This might not be the best performing solution, so think twice before deplying it to production. It is however very usefull for a quick debug session, which is where I mostly use it.
EDIT: As Cliff mentions it, you could use:
...nvarchar if there's characters that don't convert to varchar
You should be able to do this quite easily:
SELECT *
FROM WebPageContent
WHERE data.value('(/PageContent/Text)[1]', 'varchar(100)') LIKE 'XYZ%'
The .value method gives you the actual value, and you can define that to be returned as a VARCHAR(), which you can then check with a LIKE statement.
Mind you, this isn't going to be awfully fast. So if you have certain fields in your XML that you need to inspect a lot, you could:
create a stored function which gets the XML and returns the value you're looking for as a VARCHAR()
define a new computed field on your table which calls this function, and make it a PERSISTED column
With this, you'd basically "extract" a certain portion of the XML into a computed field, make it persisted, and then you can search very efficiently on it (heck: you can even INDEX that field!).
Marc
Another option is to search the XML as a string by converting it to a string and then using LIKE. However as a computed column can't be part of a WHERE clause you need to wrap it in another SELECT like this:
SELECT * FROM
(SELECT *, CONVERT(varchar(MAX), [COLUMNA]) as [XMLDataString] FROM TABLE) x
WHERE [XMLDataString] like '%Test%'
This is what I am going to use based on marc_s answer:
SELECT
SUBSTRING(DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)'),PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')) - 20,999)
FROM WEBPAGECONTENT
WHERE COALESCE(PATINDEX('%NORTH%',DATA.value('(/PAGECONTENT/TEXT)[1]', 'VARCHAR(100)')),0) > 0
Return a substring on the search where the search criteria exists

How do I query XML stored as text?

I have a table in a SQL Server 2005 database that logs purchases like so:
ID (PK, int, not null)
Request (text, null)
Response (text, null)
MerchantId (varchar(14), null)
Amount (money, null)
The Request and Response fields are really storing XML. I can't change the data type to XML. I need to draw a query that will get data out of the 2 text-as-XML fields in addition to data that is in the table itself.
I'm not sure where to start with this. Most of my searches come back with questions about LINQ-to-SQL, and the SQLXML results I get don't seem to be able to handle sets of data. Where should I be focusing my search?
Use CAST(text AS XML) to obtain an XML typed column that can be manipulated at the server (use value, nodes and query xml methods on it).
SELECT ID,
CAST(Request AS XML) As RequestXml,
CAST(Request AS XML) As ResponsetXml,
MerchantId,
Amount
FROM <table>
If you only need the XML in the client, then you can just return the text and then use whatever is your client side XML technology of choice (XmlDocument, XPathDocument, Linq 2 xml) they all allow you to cosntruct a fragment from a string.
You could cast the data on the fly, e.g.:
CAST(Request AS XML)
SELECT request.VALUE(/xpath/query)
FROM
(
SELECT
CAST(Request as XML) request,
CAST(Response as XML) response
FROM purchaseTbl
WHERE ...
) tbl
WHERE ...
You can always CAST( [Request] AS XML ) and then use all of the regular XML functions to extract data from it.
If you are using SQL server (2005 onwards), one possibility could be to write a user defined function in a .Net language that parses out the XML from a field and returns that data as part of teh query