SQL. XML values from column. How to get? - sql

For example I have table "BigApple" with three columns.
first column includes numbers
second column includes some text
third column includes XML files.
My question is: how to get to the third column of the specific values for a particular tag?

Use one of the XML methods on XML column https://msdn.microsoft.com/en-us/library/ms190798.aspx

In fact, if you have the same kind of XML data in the third column you can read specific tag values easily.
Please refer to examples on SQL XML query using a single XML variable
and example to query XML column in SQL database table using CROSS APPLY

Mao, how do you expect to get an answer which really helps you without showing your data? It can be trivial 'til really tricky to get data from an XML. Do you need only one particular tag? Or are there several data? Nested data?
One example for a trivial read might be this:
CREATE TABLE #tmpTbl(Number INT, SomeText VARCHAR(100),SomeXML XML);
INSERT INTO #tmpTbl VALUES
(1,'Test1','<root><a>xmlA1</a><b>xmlB1</b></root>')
,(2,'Test2','<root><a>xmlA2</a><b>xmlB2</b></root>');
SELECT Number
,SomeText
,SomeXML.value('(/root/a)[1]','varchar(10)') AS Tag_a
FROM #tmpTbl;
GO
DROP TABLE #tmpTbl;
The result
Number SomeText Tag_a
1 Test1 xmlA1
2 Test2 xmlA2

Related

How to convert generic XML to a table row in PostgreSQL?

PostgresSQL v12.5
There is a table with single column containing strings formatted as XML.
create table XMLDATA (value text);
--------
text
--------
<something> <a>uyt</a> <b>xyz</b> </something>
<something> <a>ryu</a> <b>sdg</b> </something>
For simplicity let's claim that there are no nesting: all tags inside <something> contain primitive values (strings).
Assuming that there are much more elements than <a> and <b> inside, it would be great to have an option to convert these values into a relational form without enumerating all of the nested tags manually.
Was trying to get something in documentation related to XPATH, XMLTABLE, XPATH_TABLE, but there are small number of examples that did not help me to reveal the full power of these functions.
What I am looking for is a function special_function with results like
select * from special_function(XMLDATA);
a | b
-----------
uyt | xyz
ryu | sdg
Could you help me find a functionality of PostgreSQL that automatically recognizes XML tags and convert their content into columns?
without enumerating all of the nested tags manually.
That's not possible.
One fundamental restriction of SQL is, that the number, data types and names of all columns need to be known to the database before the query starts executing. SQL can't do this "at runtime" and change structure of the query based on data that is retrieved.
You can extract the content using xmltable() - but as explained, there is no way without specifying each output column.
select x.*
from xmldata d
cross join xmltable('/something' passing d.value
columns a text path 'a',
b text path 'b') as x
This assumes value is declared with the data type xml (which it should be). If it's not the case, you need to cast it: passing d.value::xml

Stored Procedure for converting rows to columns in SQL Server

I'm looking for an efficient way of how to convert rows to columns in SQL Server. I tried in Toad for Oracle, but now I want it in SQL Server.
This is my example:
CID SENTENCE
1 Hello; Hi;
2 Why; What;
The result should be like
CID SENTENCE
1 Hello
1 Hi
2 Why
2 What
Would you please help me with it?
I would advise you to rethink your database design. It's almost never a good idea to store data in a delimited string in any relational database.
If it's impossible to change your database design, you need to use some UDF to split strings.
There are many different approaches to split strings in sql server, read this article on the differences between the common ways.
You can probably change your chosen split string function to take the cid as well as the sentence as a variable and have it return the data exactly as your desired output for each row in your table.
Then all you have to do is a select from your table with an inner join with the udf on the cid.
try
declare #var table (CID int, SENTENCE varchar(50))
insert into #var(CID,SENTENCE) values
(1,'Hello; Hi;'),
(2,'Why; What;')
select cid,t.c.value('.','varchar(50)') as val
from (select cid,x=cast('<t>'+ replace(stuff(sentence,len(sentence),1,''),';','</t><t>')+'</t>' as xml)
from #var) a cross apply x.nodes('/t') t(c)

Compare XML data to String

I have a table that houses a bunch of data in an XML field. I can get to the data and display what I need in the select statement, but I also need to use that to compare to another table that houses a translation I am trying to do. Is there a way to compare the value being returned from the XML data to a string value that exists in another table?
The code in my select to return the XML data is:
prv.reported_attributes.value('(/row[#ATTRIBUTE="FIELD"][1])/#VALUE', 'varchar(5)')
I need to compare that text output to another table, but I keep getting NULL like the values I am trying to compare do not match. I have confirmed they do in fact have matches.

SQL query to check for inclusion of any element from an array

I have a database column containing a string that might look something like this u/1u/3u/19/g1/g4 for a particular row.
Is there a performant way to get all rows that have at least one of the following elements ['u/3', 'g4'] in that column?
I know I can use AND clauses, but the number of elements to verify against varies and could become large..
I am using RoR/ActiveRecord in my project.
in sql server, you can use XML to convert your list of search params into a record set, then cross join that with the base table, and do charIndex() to see if the column contains the substring.
Since i don't know your table or column names, i used a table (persons) that i already had data in, which has a column 'phone_home'. To search for any phone number that contains '202' or '785' i would use this query:
select person_id,phone_home,Split.data.value('.', 'VARCHAR(10)')
from (select *, cast('<n>202</n><n>785</n>' as XML) as myXML
from persons) as data cross apply myXML.nodes('/n') as Split(data)
where charindex(Split.data.value('.', 'VARCHAR(10)'),data.phone_Home) > 0
you will get duplicate records if it matches more than one value, so throw a distinct in there and remove the Split from the select statement if that is not desired.
Using xml in sql is voodoo magic to me...i got the idea from this post http://www.sqljason.com/2010/05/converting-single-comma-separated-row.html
no idea what performance is like...but at least there aren't any cursors or dynamic sql.
EDIT: Casting the XML is pretty slow, so i made it a variable so it only gets cast once.
declare #xml XML
set #xml = cast('<n>202</n><n>785</n>' as XML)
select person_id,phone_home,Split.persons.value('.', 'VARCHAR(10)')
from persons cross apply #xml.nodes('/n') as Split(persons)
where charindex(Split.persons.value('.', 'VARCHAR(10)'),phone_Home) > 0

How to append data from one table in another where one column is xml with sql?

Actually both tables are the same, and I just need to merge data. Problem is that one column is defined with XML shema, which is same in both tables, and for my query I am getting this error from sql server studio:
"Implicit conversion between XML types constrained by different XML schema collections is not allowed. Use the CONVERT function to run this query."
Help me writedown this query.
I have something like this:
INSERT INTO table1
SELECT * FROM table2
WHERE id NOT IN (select id from table1);
Without more info on your table structure and the xml schemas I'm not sure how much assistance I can be. That said there's an article that discusses this exact problem here
http://sqlblogcasts.com/blogs/martinbell/archive/2010/11/08/Using-XML-Schemas.aspx
And his example of using the convert statement to overcome exactly this problem is as follows.
INSERT INTO [dbo].[Test_ProductModel_Content]( [CatalogDescription] )
SELECT CONVERT(XML, [CatalogDescription] )
FROM AdventureWorks2008.Production.ProductModel
WHERE [CatalogDescription] IS NOT NULL ;
GO
Hope that helps, if not post more information and I'm sure someone can help you out.