T-SQL: Display XML data using SELECT statement - sql-server-2008

I have the following XML text:
<Elements>
<imported>
<product name="Software #">0 </product>
<product name="Hardware">1000 Pieces </product>
<product name="Parts">300 </product>
<product name="Wholes sales">1000</product>
<product name="Cars">Audi (10) Porche (22) Skoda (48)</product>
<product name="Final Report">0</product>
</imported>
</Elements>
This XML data is stored in a nvarchar(max) column, and it looks like this:
I want to do a select statement (or store the info in a temp table) and display a more readable form of that XML data and extract the values of the XML nodes, something like:
Column1 | Column2
------------------
Software | 0
Hardware | 1000 pieces
I am using SQL Server 2008.

I think you can use a query after converting your string to xml like this:
DECLARE #x xml = #xml;
SELECT
c.value('#name', 'nvarchar(MAX)') AS Column1,
c.value('.[1]', 'nvarchar(MAX)') AS Column2
FROM
#x.nodes('/Elements/imported/product') As t(c);
Or an inline convert like this:
SELECT
c.value('#name', 'nvarchar(MAX)') AS Column1,
c.value('.[1]', 'nvarchar(MAX)') AS Column2
FROM
(SELECT CAST(#xml as xml) x) dt CROSS APPLY
dt.x.nodes('/Elements/imported/product') As t(c);

Related

Create JSON from SQL Server Table With Column Value as JSON Property Name

I have a table with the following schema in a SQL Azure DB (2019 compat level):
CREATE TABLE dbo.Properties
(
PropertyId int,
PropertyName nvarchar(100),
PropertyValue nvarchar(1000)
)
I'd like to take the data within this table and turn it into JSON using the value within the PropertyName column as the name of the JSON property, and obviously the PropertyValue value as the JSON property value.
EDIT 12/10/2021:
Importantly, the values within the PropertyName column will not be predictable ahead of time.
For example, consider this data in the table (3 rows):
1, "Color", "Blue"
1, "Name", "John"
1, "Cost", 5
The above would be turned into the following JSON:
{"Color":"Blue", "Name":"John", "Cost":5}
I'm obviously able to do this with a STRING_AGG function like the following:
SELECT '{' + STRING_AGG( '"' + p.PropertyName + '": ''' + p.PropertyValue,''',')
WITHIN GROUP (ORDER BY p.PropertyName) + '}' AS MyJson
FROM dbo.Properties p
GROUP BY p.Id
But I was hoping to use one of the build in JSON functions rather than hack together a big string.
FOR JSON AUTO works from the column names, so one method to get your desired result would be to PIVOT the property names into columns. For example:
SELECT Color, [Name], Cost
FROM dbo.Properties
PIVOT ( MAX( PropertyValue ) For PropertyName In ( [Color], [Name], Cost ) ) pvt
FOR JSON AUTO;
My results:
Of course this is only convenient if your JSON attributes / column names are always known and it's a simple example. For more complex examples, you are probably looking at dynamic pivot, or dynamic SQL and your STRING_AGG example isn't so bad.

Avoid escaping characters when converting from tabular data to json

I have some problems converting tabular data to JSON using the FOR JSON PATH syntax:
If i do a standard query:
SELECT b.Name FROM dbo
I get results of the form: 12/5-A-1. I need this converted to JSON data without escaping the backslash character. However, when i convert it to JSON:
SELECT b.Name FROM dbo FOR JSON PATH, WITHOUT ARRAY_WRAPPER
the result is of the form: {"Name": "12\/5-A-1"}
How can i do this transformation without escaping the backslash character and get the result {"Name": "12/5-A-1"}?
One option is to use a common table expression to generate the json, and then simply use replace when selecting from the common table expression.
First, create and populate sample data (Please save us this step in your future questions):
DECLARE #T AS TABLE
(
[Name] nvarchar(10)
)
INSERT INTO #T ([Name]) VALUES ('12/5-A-1');
The cte:
WITH CTE(Escaped) AS
(
SELECT [Name]
FROM #T
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
)
The final select:
SELECT REPLACE(Escaped, '\/','/') As Result
FROM CTE
Result:
{"Name":"12/5-A-1"}

XML reading with multiple child in SQL server

<Data>abc</Data>
<Data>def</Data>
I want to get data from above tag where child tag is under Parent tag So how to read it into one column in sql server as
Column1
abc,def
DECLARE #x XML = '<parent>
<Data>abc</Data>
<Data>def</Data>
</parent>'
SELECT STUFF((
SELECT ',' + d.value('.', 'nvarchar(20)')
FROM #x.nodes('/parent/Data') AS p(d)
FOR XML PATH('')
), 1, 1, '')
I assume the data is contained in a table with column having XML data type.
Lets assume it is inside the table
#Test(column1 XML)
The values could be retrieved as:
Select Column1.Value('(/Parent/Child)[1]','varchar(100)') as FieldName From #Test
" 1 " denotes that a scalar value is to be returned.
For more information :
Pinal Dave Article

Export mysql rows into different files

I have a mySQL table which contains html code and some other information.
One example like this:
SELECT id, lang, html
FROM mytable t
WHERE type = 10
give the result:
id lang html
-------------------------------------------------------
20 fr '<html> ... html code here </html>'
21 de '<html> ... html code here </html>'
22 it '<html> ... html code here </html>'
23 en '<html> ... html code here </html>'
and my idea is to export the html code into one file per lines like
20_fr.html will contains the html columns for id 20
21_de.html will contains the html columns for id 21
etc...
Is it possible to do so in SQL language only like this example for exporting all rows into one file.
I know I can do it with Java or any other language but I am interested only by a SQL (a stored procedure could be ok).
You can use the SELECT statement with the INTO and OUTFILE clauses.
See: http://dev.mysql.com/doc/refman/5.7/en/select-into.html
SELECT html
FROM mytable
WHERE lang = 'fr'
INTO OUTFILE 'frdata.txt'
The following SQL query might be used to generate one file output statement per row in the table. Note the use of the CONCAT function to build a new SQL SELECT INTO OUTFILE command per row.
SELECT CONCAT( 'SELECT html from mytable where lang=''', lang, '''', ' INTO OUTFILE ''', CAST(id AS CHAR), '_', lang, '.html'';')
FROM mytable
ORDER BY id;
This will yield the the statements:
SELECT html from mytable where lang='fr' INTO OUTFILE '20_fr.html';
SELECT html from mytable where lang='de' INTO OUTFILE '21_de.html';
SELECT html from mytable where lang='it' INTO OUTFILE '22_it.html';
...

How to export all words from sql table or sql database

Let's say we have following table.
UserId | Message
-------|-------------
1 | Hi, have a nice day
2 | Hi, I had a nice day
I need to have all { Hi,-have-a-nice-day-I-had } words separately.
Is there any way to do that ? What if I want to export words from whole database tables ?
Similar results would be also good.
try this:In Sql server 2005 or above
create table yourtable(RowID int, Layout varchar(200))
INSERT yourtable VALUES (1,'hello,world,welcome,to,tsql')
INSERT yourtable VALUES (2,'welcome,to,stackoverflow')
;WITH SplitSting AS
(
SELECT
RowID,LEFT(Layout,CHARINDEX(',',Layout)-1) AS Part
,RIGHT(Layout,LEN(Layout)-CHARINDEX(',',Layout)) AS Remainder
FROM YourTable
WHERE Layout IS NOT NULL AND CHARINDEX(',',Layout)>0
UNION ALL
SELECT
RowID,LEFT(Remainder,CHARINDEX(',',Remainder)-1)
,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(',',Remainder))
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)>0
UNION ALL
SELECT
RowID,Remainder,null
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)=0
)
SELECT part FROM SplitSting ORDER BY RowID
SQLFIDDLE DEMO
Well, ok, here it goes.
In SQL Server you can use this...
SELECT word = d.value('.', 'nvarchar(max)')
FROM
(SELECT xmlWords = CAST(
'<a><i>' + replace([Message], ' ', '</i><i>') + '</i></a>' AS xml)
FROM MyMessageTbl) T(c)
CROSS APPLY c.nodes('/a/i') U(d)
And I hope that for MySQL you can use the same thing, using XML support - ExtractValue() etc.
EDIT: explanation
- replace([Message], ' ', '</i><i>') replaces e.g. 'my word' with 'my</i><i>word'
- then I add the beginning and the end of xml -> '<a><i>my</i><i>word</i></a>', so I have a valid xml... and cast it to xml type to be able to do something with it
- I select from that xml and shred xml nodes '/a/i' it to rows using CROSS APPLY c.nodes('/a/i');
alias rows using U(d), so one 'i' maps to column d (e.g. 'my')
- d.value('.', 'nvarchar(max)') extracts node content and casts it to character type