Parsing XML into a SQL table WITHOUT predefining structure. Possible? - sql-server

So using the code below... can I parse #xml_data into a table structure without predefining the structure?
DECLARE #receiveTable TABLE(xml_data XML) DECLARE #xml_data XML
DECLARE #strSQL NVARCHAR(2000)
SET #strSQL = 'SELECT * INTO #tmp1 FROM sysobjects;
DECLARE #tbl TABLE(xml_data xml);
DECLARE #xml xml;
Set #xml = (Select * from #tmp1 FOR XML AUTO);
INSERT INTO #tbl(xml_data) SELECT #xml;
SELECT * FROM #tbl'
INSERT INTO #receiveTable EXEC (#strSQL)
SET #xml_data = (SELECT * FROM #receiveTable)
SELECT #xml_data

As in your #xml_data, if /element[1] has the same number of attributes as /element[n] and they're in the same order ltr, you can.
It's not pretty, but you can:
declare #tbl_xml xml
set #tbl_xml = (
select #xml_data.query('
<table>
{for $elem in /descendant::node()[local-name() != ""]
return <row name="{local-name($elem)}">
{for $attr in $elem/#*
return <col name="{local-name($attr)}" value="{$attr}" />}
</row>}
</table>'
)
)
declare #sql_def_tbl varchar(max)
select #sql_def_tbl =
coalesce(#sql_def_tbl,'')
+'declare #tbl table ('+substring(csv,1,len(csv)-1)+') '
from (
select (
select ''+col.value('#name','varchar(max)')+' varchar(max),'
from row.nodes('col') r(col) for xml path('')
) csv from #tbl_xml.nodes('//row[1]') n(row)
) x
declare #sql_ins_rows varchar(max)
select #sql_ins_rows =
coalesce(#sql_ins_rows,'')
+'insert #tbl values ('+substring(colcsv,1,len(colcsv)-1)+') '
from (
select (
select ''''+col.value('#value','varchar(max)')+''','
from row.nodes('col') r(col) for xml path('')
) colcsv from #tbl_xml.nodes('//row') t(row)
) x
exec (#sql_def_tbl + #sql_ins_rows + 'select * from #tbl')

Related

How can I execute "for json path" in dqe and insert result of execute in temp table in SQL Server?

DECLARE #QUERY NVARCHAR(MAX) = 'SELECT * FROM Student FOR JSON PATH'
DECLARE #TABLE TABLE(RESULT NVARCHAR(MAX))
INSERT #TABLE
EXEC (#QUERY)
Error:
The for json clause is not allowed in a INSERT statement
you can try this -
DECLARE #TABLE TABLE(RESULT NVARCHAR(MAX))
DECLARE #QUERY NVARCHAR(MAX) = '
;WITH x(a) as
(
SELECT
*
FROM Student FOR JSON AUTO
)
Select * from x
'
Insert #TABLE
EXEC (#QUERY)
Select * from #TABLE;

Querying a table for a list then use that list in a select statement

Lets say I have a table that holds a list of other tables
Declare #MyList varchar(max)
#MyList = Select tablename from ListofTables
it brings back a list of 50 tablenames
How can I use that list of tablenames in a single select statement? I was thinking a for loop or something maybe?
For each tablename in #MyList
Select * from tablename
You may try with the next approach:
-- Table
CREATE TABLE #ListOfTables (
[TableName] varchar(max)
)
INSERT INTO #ListOfTables
([TableName])
VALUES
('Table1'),
('Table2'),
('Table3'),
('Table4'),
('Table5'),
('Table6'),
('Table7'),
('Table8'),
('Table9')
-- Statement
DECLARE #stm nvarchar(max)
SET #stm = N''
SELECT #stm = #stm + N'SELECT * FROM ' + QUOTENAME([TableName]) + N'; '
FROM #ListOfTables
/*
-- Or using FOR XML PATH
SELECT #stm = (
SELECT CONCAT(N'SELECT * FROM ', QUOTENAME([TableName]), N'; ')
FROM #ListOfTables
FOR XML PATH('')
)
*/
PRINT #stm
EXEC sp_executesql #stm

how to remove duplicates from a comma seperated string in sql server

how to remove duplicate values from the comma seperated string in sql server. Without using functions
Declare #data varchar(max) = '34.22,768.55,34.22,123.34,12,999.0,999.0'
My expected result should be
34.22,768.55,123.34,12,999.0
i tried this query but it doesn't remove duplicates from the variable.
Declare #data varchar(max) = '34.22,768.55,34.22,123.34,12,999.0,999.0'
set #data= (select '' + cast(cast('<d>'+replace(#data, ', ',',</d><d>')+'</d>' as xml).query('distinct-values(/d)') as varchar(max)) +'')
Please try this -
DECLARE #x AS XML=''
Declare #finalstring varchar(max) = ''
DECLARE #Param AS VARCHAR(100) = '34.22,768.55,34.22,123.34,12,999.0,999.0'
SET #x = CAST('<A>'+ REPLACE(#Param,',','</A><A>')+ '</A>' AS XML)
select #finalstring = #finalstring + value + ',' from (
SELECT t.value('.', 'VARCHAR(10)') Value FROM #x.nodes('/A') AS x(t))p
GROUP BY value
PRINT SUBSTRING(#finalstring,0,LEN(#finalstring))
OUTPUT
12,123.34,34.22,768.55,999.0
For sql 2016+
Declare #data varchar(max) = '34.22,768.55,34.22,123.34,12,999.0,999.0'
Declare #finalstring varchar(max) = ''
select #finalstring = #finalstring + value + ',' from string_split(#data,',')
GROUP BY value
PRINT SUBSTRING(#finalstring,0,LEN(#finalstring))
OUTPUT
12,123.34,34.22,768.55,999.0
Try this
Declare #data varchar(max) = '34.22,768.55,34.22,123.34,12,999.0,999.0'
SELECT STUFF(
(
SELECT DISTINCT ',' + UniqNum FROM
(
SELECT CAST('<d>'+replace(#data, ',','</d><d>')+'</d>' AS XML) AS numberXml
) as t1
CROSS APPLY
(
SELECT my_Data.D.value('.','varchar(50)') as UniqNum
FROM t1.numberXml.nodes('d') as my_Data(D)
) t2
FOR XML PATH('')
), 1, 1, '')
Result
UniqNumber
---------------------------
12,123.34,34.22,768.55,999.0
Try This
Declare #data varchar(max) = '34.22,768.55,34.22,123.34,12,999.0,999.0'
;WITH CTE
AS
(
SELECT
MyStr = SUBSTRING(#data,CHARINDEX(',',#Data)+1,LEN(#data)),
Val = SUBSTRING(#data,1,CHARINDEX(',',#data)-1)
UNION ALL
SELECT
MyStr = CASE WHEN CHARINDEX(',',MyStr)>0
THEN SUBSTRING(MyStr,CHARINDEX(',',MyStr)+1,LEN(MyStr))
ELSE NULL END,
Val = CASE WHEN CHARINDEX(',',MyStr)>0
THEN SUBSTRING(MyStr,1,CHARINDEX(',',MyStr)-1)
ELSE MyStr END
FROM CTE
WHERE ISNULL(REPLACE(MyStr,',',''),'')<>''
)
SELECT
Val = SUBSTRING(List,1,LEN(List)-1)
FROM
(
SELECT
DISTINCT Val+','
FROM CTE
WHERE ISNULL(MyStr ,'')<>''
FOR XML PATH('')
)Q(List)
My Result
12,123.34,34.22,768.55,999.0
Just an another simple way of doing it.
Declare #data Nvarchar(max) = N'34.22,768.55,34.22,123.34,12,999.0,999.0'
, #data2 Nvarchar(max)='';
SELECT #data = N'SELECT #DATA_DIST= #DATA_DIST+VAL+'',''
FROM (SELECT '''+replace(#data,',',''' AS VAL UNION SELECT ''')+''')A';
EXECUTE sp_executesql #data,N'#DATA_DIST varchar(MAX) OUTPUT',#DATA_DIST=#data2 OUTPUT;
SELECT LEFT(#data2,LEN(#data2)-1);
Result:
12,123.34,34.22,768.55,999.0

Showing "Invalid object name " in sqlServer?

While Executing the Following query it showing the Invalid object name '#temp1'. can any body knows the error occurred due to which reason this is my orginal code i used to fetch code , her differnt tables are formed i need to get the sum of the each row of each table
DECLARE #t TABLE (
id int IDENTITY(1,1),
BranchName nvarchar(max)
)
DECLARE #n int = 0,
#i int = 1,
#BranchName nvarchar(max),
#sql nvarchar(max),
#columns nvarchar(max)
INSERT INTO #t
SELECT DISTINCT BranchName
FROM ALX_Branches
SELECT #n = ##ROWCOUNT
WHILE #n >= #i
BEGIN
SELECT #BranchName = BranchName
FROM #t
WHERE id = #i
SELECT #columns = (
SELECT DISTINCT ','+QUOTENAME([SubInventory])
FROM #MyTempTable
WHERE [BranchName] = #BranchName
FOR XML PATH('')
)
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt'
EXEC sp_executesql #sql
select * from #temp1
Firstly, there is no need for creating #temp1 table before.
because you are using "Select * into" that already create table within it.
Suppose type this note as a comment, but I don't have enough reputation score.
The reason of
Invalid object name '#temp1'
is: the variable #sql is NULL because #temp1 is not created yet via "Select * into" clause.
so append selecting from #temp1 within dynamic sql as the following:
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt
select * from #temp1 '
EXEC sp_executesql #sql

Get results for EXECUTE(#QUERY) and FOR XML

I have a dynamic query with FOR XML clause.
How can I get result from it ?
DECLARE #QUERY NVARCHAR(MAX);
-- Here dynamicaly generated query. But for example i made it static
SET #QUERY = N'SELECT [CLMN]
FROM (
SELECT 1 as [CLMN]
) TBL FOR XML PATH(''TBL'')';
EXECUTE(#QUERY);
I need insert result to any variable from this code:
EXECUTE(#QUERY);
You can do it like this:
declare #QUERY nvarchar(max), #RESULT xml
set #QUERY = N'select #RESULT = (
SELECT [CLMN]
FROM (
SELECT 1 as [CLMN]
) TBL
FOR XML PATH(''TBL'')
)'
execute sp_executesql #QUERY, N'#RESULT xml output', #RESULT = #RESULT output
select #RESULT
Just pass outer variable into dynamic query, and assign result of select ... for xml to this variable in query.

Resources