Joining with Temp table outside XML element - sql-server

I am new to XML+SQL module and I have a code that selects a regular column and a whole bunch of XML data.
Below is my sample code:
create table #temp(cid int, val int)
insert into #temp values
(1,11),
(2,12),
(3,12)
select
t1.cid,
xml =
(
select t2.cid,t2.val
from #temp t2
join #temp t1 on t2.cid = t1.cid
for xml Path(''), type)
from #temp t1
drop table #temp
desired output is:
Rexter link: http://rextester.com/HLZS59752
Any help ??

If I understand your question.
Example
select
t1.cid,
xml = (Select t1.* for xml path('') )
from #temp t1
Returns
cid xml
1 <cid>1</cid><val>11</val>
2 <cid>2</cid><val>12</val>
3 <cid>3</cid><val>12</val> -- Last record in #temp is (3,12)

Thanks #John Cappelletti for that answer. That helped. One mroe solution I found was:
select
t1.cid,
xml =
(
select t2.cid,t2.val
from #temp t2
where t1.cid = t2.cid
for xml Path(''), type)
from #temp t1
Instead of join, I added the condition in Where clause and it worked.
Updated Rexter link: http://rextester.com/MGXDC39580

Related

tsql for xml path insert mutliple the same named rows

Lets say I have table T with one column A.
What I would like to achieve as result is xml like this :
<not>
<mes>not important what include</mes>
<A>1</A>
<A>2</A>
<A>3</A>
<A>4</A>
...
</not>
Was trying something similar to :
SELECT
'important' AS [mes],
(select A as [A] from T)- of course that part is incorrect but don't know how to handle it
FROM T2
FOR XML PATH ('not');
Please advice.
Updated QUERY
SET #SQL = '
WITH XMLNAMESPACES (''https://something..'' as ns)
SELECT
Q.DocumentType AS [#type],
Q.ReferenceNo AS [#ref],
Q.Id AS [#id],
D.DocId AS [#docId],
N.NotId AS [#notId],
CONVERT(char(10), N.CreationDate, 126) AS [#notdate],
''mes'' AS [mes/#content],
#mes2 AS [mes/content],
[mes] = ''important'' ,
(select A from '+ Cast(#TableName as VARCHAR(60))+' FOR XML PATH (''''), type)
FROM
[DB].[dbo].[tab1] AS Q
LEFT JOIN [DB].[dbo].[tab2] AS D ON Q.ID=D.ID
LEFT JOIN [DB].[dbo].[tab3] AS N ON D.ID=N.DocId
WHERE
Q.ID='+ Cast(#Id as varchar(15))+'
FOR XML PATH (''not'')';
execute (#SQL);
Perhaps this will help
-- Just a DEMONSTRATIVE Table Variable
--------------------------------------------
Declare #YourTable Table ([A] varchar(50))
Insert Into #YourTable Values
(1)
,(2)
,(3)
,(4)
SELECT [mes] = 'important'
,( Select A from #YourTable For XML Path(''),type )
FOR XML PATH ('not');
Results
<not>
<mes>important</mes>
<A>1</A>
<A>2</A>
<A>3</A>
<A>4</A>
</not>

PATINDEX all values of a column

I'm making a query that will delete all rows from table1 that has its column table1.id = table2.id
table1.id column is in nvarchar(max) with an xml format like this:
<customer><name>Paulo</name><gender>Male</gender><id>12345</id></customer>
EDIT:
The id column is just a part of a huge XML so the ending tag may not match the starting tag.
I've tried using name.nodes but it only applies to xml columns and changing the column datatype is not a choice, So far this is the my code using PATINDEX
DELETE t1
FROM table1 t1
WHERE PATINDEX('%12345%',id) != 0
But what I need is to search for all values from table2.id which contains like this:
12345
67890
10000
20000
30000
Any approach would be nice like sp_executesql and/or while loop, or is there a better approach than using patindex? thanks!
Select *
--Delete A
From Table1 A
Join Table2 B on CharIndex('id>'+SomeField+'<',ID)>0
I don't know the name of the field in Table2. I am also assuming it is a varchar. If not, cast(SomeField as varchar(25))
EDIT - This is what I tested. It should work
Declare #Table1 table (id varchar(max))
Insert Into #Table1 values
('<customer><name>Paulo</name><gender>Male</gender><id>12345</id></customer>'),
('<customer><name>Jane</name><gender>Femail</gender><id>7895</id></customer>')
Declare #Table2 table (SomeField varchar(25))
Insert into #Table2 values
('12345'),
('67890'),
('10000'),
('20000'),
('30000')
Select *
--Delete A
From #Table1 A
Join #Table2 B on CharIndex('id>'+SomeField+'<',ID)>0
;with cteBase as (
Select *,XMLData=cast(id as xml) From Table1
)
Select *
From cteBase
Where XMLData.value('(customer/id)[1]','int') in (12345,67890,10000,20000,30000)
If you are satisfied with the results, change the final Select * to Delete

Grouping XML Elements in FOR XML Clause

I am trying to create a structure xml document from my temp table .The temp table is in the following format .
CREATE TABLE #Temp1 ( Name Char( 30 ), seqid integer, salary int );
INSERT INTO #Temp1 VALUES('DEAL' ,123,6)
INSERT INTO #Temp1 VALUES('DEAL' ,56,6)
INSERT INTO #Temp1 VALUES('TRACNHE' ,1253,56)
INSERT INTO #Temp1 VALUES('TRACNHE' ,5,65)
INSERT INTO #Temp1 VALUES('ASSET' ,56,23)
I am trying to create an xml format in the following form :
<Response>
<Deal>
<seqid="123" salary="6" />
<seqid="56" salary="6" />
<Deal>
<TRACNHE>
<seqid="1253" salary="56"/>
<seqid="5" salary="65"/>
</TRACNHE>
<ASSET>
<seqid="56" salary="23"/>
</ASSET>
</Response>
SELECT Name, (SELECT SEQID FROM #TEMP1 T WHERE T.Name = T1.Name)
FROM (SELECT DISTINCT NAME FROM #TEMP1 ) T1
FOR XML PATH('rEPONSE')
DROP TABLE #Temp1
DROP TABLE #Temp1
I tried the above query but says that subquery returned more than 1 value
Could you let me know as to what i am missing in this query .
Is there a better way to handle this scenario.
Thanks in advance
based on your requirement, i'm seeing there are 2 types of complexities
You are trying to get the xml with grouped items.
For each group trying to create an xml element with two attributes
without any proper name
<seqid="1253" salary="56"/>
instead of
<ss seqid="1253" salary="56"/>
just look into this below query, it may help
SELECT
(SELECT
seqid 'ss/#seqid'
, salary 'ss/#salary'
FROM Temp1 as t where t.Name = 'Deal'
FOR XML PATH('Deal') , TYPE
) ,
(SELECT
seqid 'ss/#seqid'
, salary 'ss/#salary'
FROM Temp1 as t where t.Name = 'TRACNHE'
FOR XML PATH('TRACNHE') , TYPE
) ,
(SELECT
seqid 'ss/#seqid'
, salary 'ss/#salary'
FROM Temp1 as t where t.Name = 'ASSET'
FOR XML PATH('ASSET') , TYPE
)
FOR XML PATH(''), ROOT('Response');

String Replace column data with data from another table

I have two tables:
TableA:
ID Values
---------------
1 Q
2 B
3 TA
4 BS
TableB:
RawValue Value
------------------
[1][4] QBS
[2][1][3] BQTA
I need to generate TableB values with its given RawValues. each [X] in rawvalue is the ID coulmn of TableA and shoud be replace with its value .
[1][4] means that Value of TableA with has ID of 1 (Q) and Value of TableA with has ID of 4 (BS) then should equal to QBS.
can anyone suggest a way to do it?
this is what I have already tried:
update tableb set value=replace(rawvalue,'[' + (select id from tablea where id = cast(replace(replace(rawdata,'[',''),']','') as int)) + ']',
(select values from tablea where id = cast(replace(replace(rawdata,'[',''),']','') as int)))
By the way: this is still in test process and I can totally change tables, rowvalue format and replacement methods if anyone has a better idea.
declare #tableA table (id int, value varchar(50))
insert into #tableA (id, value)
select 1, 'Q' union all
select 2, 'B' union all
select 3, 'TA' union all
select 4, 'BS'
declare #tableB table (rawdata varchar(255), value varchar(255))
insert into #tableB (rawdata)
select '[1][4]' union all -- QBS
select '[2][1][3]' -- BQTA
update b
set value = (
select a.value + ''
from #tableA a
cross apply (select charindex ('[' + cast (a.id as varchar(50)) + ']', b.rawdata) as pos) p
where pos > 0
order by pos
for xml path('')
)
from #tableB b
select * from #tableB
P.S. I would recommend not to name field similar to reserved keywords (I mean Values).
Turn RawValue into XML, shred the XML to get one row for each value in RawValue and join to TableA to get the value.
Use the for xml path() trick to concatenate the values from TableA.
update TableB
set Value = (
select T.Value as '*'
from (
select row_number() over(order by T2.X) as SortOrder,
TableA.Value
from (select cast(replace(replace(TableB.RawValue, '[', '<x>'), ']', '</x>') as xml)) as T1(X)
cross apply T1.X.nodes('x') as T2(X)
inner join TableA
on TableA.ID = T2.X.value('text()[1]', 'int')
) as T
order by T.SortOrder
for xml path('')
)
SQL Fiddle

How to query for rows along with their xml representation?

I need something like
select * from tb_listings for xml auto
But I need every row to be separate, and not one big xml document.
I have tried something like the following:
select id, (select * from tb_listings a where a.id=id for xml auto) as xmldata from tb_listings
Expected output is like:
id xmldata
------------------------------------------------------------
1 <listing><name>ABC</name><xyz>123</xyz></listing>
But it doesn't seem to do what I want and it also takes a very long time to run.
Any ideas would be appreciated. :)
Edit: Figured it out:
select id, (select top 1 * from tb_listings a where a.id=b.id for xml auto) from tb_listings b
Closing.
try something like this:
DECLARE #YourTable table (PK1 int, c1 int, c2 varchar(5), c3 datetime)
INSERT INTO #YourTable VALUES (1,2,'abcde','1/1/2009')
INSERT INTO #YourTable VALUES (100,200,'zzz','12/31/2009 23:59:59')
--list all columns in xml format
SELECT
t2.PK1 --optional, can remove this column from the result set and just get the XML
,(SELECT
*
FROM #YourTable t1
WHERE t1.PK1= t2.PK1
FOR XML PATH('YourTable'), TYPE
) as Row
FROM #YourTable t2
OUTPUT:
PK1 Row
----------- ------------------------------------------------------------------------------------------
1 <YourTable><PK1>1</PK1><c1>2</c1><c2>abcde</c2><c3>2009-01-01T00:00:00</c3></YourTable>
100 <YourTable><PK1>100</PK1><c1>200</c1><c2>zzz</c2><c3>2009-12-31T23:59:59</c3></YourTable>
(2 row(s) affected)

Resources