I'm trying to generated a xml using the below code. But I'm not satisfied with the output result. Below code I'm using the cursor to get the ids for the xml to be generated and update in another table. Any help is appreciated and i'm new to xml. Thanks
DECLARE #xml_var XML;
DECLARE #ID INT;
DECLARE XML_CURSOR CURSOR FOR
SELECT id
FROM xml_temp_table
WHERE id IS NOT NULL;
OPEN XML_CURSOR;
FETCH NEXT
FROM XML_CURSOR
INTO #ID;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #xml_var =
(
SELECT
(
SELECT 'Type' AS ID,
'Initial' AS VALUE,
'' AS TAG,
'true' AS VISIBLE,
Getdate() AS HISTORY,
'' AS DESCRIPTION,
'' AS COMMENT
FROM XML_TABLE d
WHERE D.XML_ID = #ID FOR XML PATH('field'),
TYPE ) AS 'field',
(
SELECT 'OwnerName' AS ID,
'Testing_XML' AS VALUE,
'' AS TAG,
'true' AS VISIBLE,
Getdate() AS HISTORY,
'' AS DESCRIPTION,
'' AS COMMENT
FROM XML_TABLE d
WHERE D.XML_ID = #ID FOR XML PATH('field'),
TYPE ) AS 'field'
FROM XML_TABLE p
WHERE P.XML_ID = #ID FOR XML PATH('Material'),
ROOT('FormValue') );
UPDATE S
SET S.XML_COL = #xml_var,
FROM LOCATION_TABLE_XML S
WHERE S.ID = #ID;
FETCH NEXT
FROM XML_CURSOR
INTO #ID;
END;
The result i'm getting is this way
<FormValue>
<Material>
<field> ----- i dont want this
<field>
<id>Type</id>
<value>Initial</value>
<tag />
<visible>true</visible>
<history>2016-11-08T16:53:16.440</history>
<description />
<comment />
</field>
<field>
<id>OwnerName</id>
<value>Testing_XML</value>
<tag />
<visible>true</visible>
<history>2016-11-08T16:53:16.440</history>
<description />
<comment />
</field>
</field> ---- i dont want this
</Material>
</FormValue>
But I want the result in this way
<FormValue>
<Material>
<field>
<id>Type</id>
<value>Initial</value>
<tag />
<visible>true</visible>
<history>2016-11-08T16:53:16.440</history>
<description />
<comment />
</field>
<field>
<id>OwnerName</id>
<value>Testing_XML</value>
<tag />
<visible>true</visible>
<history>2016-11-08T16:53:16.440</history>
<description />
<comment />
</field>
</Material>
</FormValue>
Might be enough to let the AS 'field' away. Your FOR XML PATH('field') will wrap each row with a <field> element.
The XML returning sub-selects can be seen as scalar values handled like a normal column. By providing a column alias this whole node gets a name and this name is again translated into a wrapping <field> element.
You can either erase this, or replace it with AS [node()] or with AS [*]
Related
I want to update empty XML variable in MSSQL
i try every solutions like replace, outer apply , modify but nothing working
please help me find a solutions
<ArrayOfField xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Field>
<FieldType>1</FieldType>
<DataType>1</DataType>
<Label>department</Label>
<Name>department</Name>
<Description />
<Min />
<Max />
<DefaultValue />
<Required>0</Required>
<SelectItems />
<Formula />
<DataSourceUID xsi:nil="true" />
<TrueText />
<FalseText />
<UnconfirmtyRule xsi:nil="true" />
<UnconfirmtyRequired xsi:nil="true" />
<UnconfirmityFormUID xsi:nil="true" />
<ConfirmationStatus xsi:nil="true" />
<ConfirmationUserBasedType xsi:nil="true" />
<ConfirmationRightUsers />
<Newline>false</Newline>
<ColumnWith>12</ColumnWith>
<Offset>0</Offset>
</Field>
<Field>
<FieldType>1</FieldType>
<DataType>4</DataType>
<Label>Test</Label>
<Name>test</Name>
<Description />
<Min />
<Max />
<DefaultValue />
<Required>0</Required>
<SelectItems />
<Formula />
<TrueText />
<FalseText />
<UnconfirmtyRule xsi:nil="true" />
<UnconfirmtyRequired xsi:nil="true" />
<UnconfirmityFormUID xsi:nil="true" />
<ConfirmationStatus xsi:nil="true" />
<ConfirmationUserBasedType xsi:nil="true" />
<ConfirmationRightUsers />
<Newline>false</Newline>
<ColumnWith>12</ColumnWith>
<Offset>0</Offset>
</Field>
</ArrayOfField>
I want update DefaultValue if DataType = 1
New DefaultValue like <DefaultValue>TODAY()<DefaultValue/>
I try this code but not update anything what is my mistake?
DECLARE #SearchType NVARCHAR(100)=N'1';
DECLARE #ReplaceWith NVARCHAR(100)=N'TODAY()';
UPDATE FormSchema
SET Fields.modify('replace value of
(/ArrayOfField
/Field[DataType=sql:variable("#SearchType")]
/DefaultValue/text())[1]
with sql:variable("#ReplaceWith")')
WHERE Fields.exist('/ArrayOfField
/Field[DataType=sql:variable("#SearchType")]')=1;
You need to use different XML modify operations depending on whether the target element is empty or not (i.e.: it contains no text as opposed to being xsi:nil="true"). For example...
--
-- Setup data...
--
create table dbo.FormSchema (
Fields xml
);
insert dbo.FormSchema (Fields) values
(N'<ArrayOfField>
<Field>
<DataType>1</DataType>
<DefaultValue>Hello, world!</DefaultValue>
</Field>
<Field>
<DataType>2</DataType>
<DefaultValue />
</Field>
</ArrayOfField>'),
(N'<ArrayOfField>
<Field>
<DataType>1</DataType>
<DefaultValue />
</Field>
<Field>
<DataType>3</DataType>
<DefaultValue />
</Field>
</ArrayOfField>');
--
-- Perform updates...
--
DECLARE
#SearchType NVARCHAR(100) = N'1',
#ReplaceWith NVARCHAR(100) = N'TODAY()';
UPDATE dbo.FormSchema
SET Fields.modify('
replace value of (/ArrayOfField/Field[DataType=sql:variable("#SearchType")]/DefaultValue/text())[1]
with sql:variable("#ReplaceWith")
')
WHERE Fields.exist('(/ArrayOfField/Field[DataType=sql:variable("#SearchType")]/DefaultValue/text())[1]')=1;
UPDATE dbo.FormSchema
SET Fields.modify('
insert text{sql:variable("#ReplaceWith")}
into (/ArrayOfField/Field[DataType=sql:variable("#SearchType")]/DefaultValue)[1]
')
WHERE Fields.exist('(/ArrayOfField/Field[DataType=sql:variable("#SearchType")]/DefaultValue)[1]')=1
AND Fields.exist('(/ArrayOfField/Field[DataType=sql:variable("#SearchType")]/DefaultValue/text())[1]')=0;
--
-- Check results...
--
SELECT * FROM dbo.FormSchema;
Which yields the results:
Fields
<ArrayOfField><Field><DataType>1</DataType><DefaultValue>TODAY()</DefaultValue></Field><Field><DataType>2</DataType><DefaultValue /></Field></ArrayOfField>
<ArrayOfField><Field><DataType>1</DataType><DefaultValue>TODAY()</DefaultValue></Field><Field><DataType>3</DataType><DefaultValue /></Field></ArrayOfField>
I need to insert an external XML file data into a SQL Server table. I tried the below code. But this inserts a single record with NULL values for all the columns
Declare #xml XML
Select #xml =
CONVERT(XML,bulkcolumn,2) FROM OPENROWSET(BULK
'C:\Users\PC901\Downloads\Tags.xml',SINGLE_BLOB) AS X
SET ARITHABORT ON
TRUNCATE TABLE Tags
Insert into Tags
(
ID,WikiPostId,ExcerptPostId,Count,TagName
)
Select
P.value('ID[1]','BIGINT') AS ID,
P.value('WikiPostId[1]','BIGINT') AS WikiPostId,
P.value('ExcerptPostId[1]','BIGINT') AS ExcerptPostId,
P.value('Count[1]','BIGINT') AS Count,
P.value('TagName[1]','VARCHAR(100)') AS TagName
From #xml.nodes('/tags') PropertyFeed(P)
SELECT * FROM Tags
and the sample XML would be
<?xml version="1.0" encoding="utf-8"?>
<tags>
<row Id="1" TagName=".net" Count="283778" ExcerptPostId="3624959" WikiPostId="3607476" />
<row Id="2" TagName="html" Count="826083" ExcerptPostId="3673183" WikiPostId="3673182" />
<row Id="3" TagName="javascript" Count="1817846" ExcerptPostId="3624960" WikiPostId="3607052" />
<row Id="4" TagName="css" Count="588062" ExcerptPostId="3644670" WikiPostId="3644669" />
<row Id="5" TagName="php" Count="1286873" ExcerptPostId="3624936" WikiPostId="3607050" />
</tags>
Here you go:
declare #xml xml = '<?xml version="1.0" encoding="utf-8"?>
<tags>
<row Id="1" TagName=".net" Count="283778" ExcerptPostId="3624959" WikiPostId="3607476" />
<row Id="2" TagName="html" Count="826083" ExcerptPostId="3673183" WikiPostId="3673182" />
<row Id="3" TagName="javascript" Count="1817846" ExcerptPostId="3624960" WikiPostId="3607052" />
<row Id="4" TagName="css" Count="588062" ExcerptPostId="3644670" WikiPostId="3644669" />
<row Id="5" TagName="php" Count="1286873" ExcerptPostId="3624936" WikiPostId="3607050" />
</tags>'
Select
P.value('#Id','BIGINT') AS ID,
P.value('#WikiPostId','BIGINT') AS WikiPostId,
P.value('#ExcerptPostId','BIGINT') AS ExcerptPostId,
P.value('#Count','BIGINT') AS Count,
P.value('#TagName','VARCHAR(100)') AS TagName
From #xml.nodes('/tags/row') PropertyFeed(P)
outputs
ID WikiPostId ExcerptPostId Count TagName
----------- -------------------- -------------------- -------------------- ----------
1 3607476 3624959 283778 .net
2 3673182 3673183 826083 html
3 3607052 3624960 1817846 javascript
4 3644669 3644670 588062 css
5 3607050 3624936 1286873 php
(5 rows affected)
I have a table EVENTS:
Name Event Gift Label
Jeff Birthday Card Happy Birthday
Jeff Birthday Present Jeff's prezzy
Maisey Promotion Cake Well Done!
Maisey Birthday Card Happy Birthday
Maisey Birthday Cake Another Year Older!
Here's the code to produce that table:
DECLARE #TempTable TABLE
(
[name] VARCHAR(250),
[event] VARCHAR(250),
[gift] VARCHAR(250),
[label] VARCHAR(2500)
);
INSERT INTO #TempTable([name], [event], [gift], [label]) VALUES
('Jeff','Birthday','Card','Happy Birthday'),
('Jeff','Birthday','Present','Jeff`s prezzy'),
('Maisey','Promotion','Cake','Well Done!'),
('Maisey','Birthday','Card','Happy Birthday'),
('Maisey','Birthday','Cake','Another Year Older!')
Which I would like to generate the following XML from:
<celebrations>
<person name="Jeff">
<events>
<event name="Birthday">
<gifts>
<gift name="Card" Value="Happy Birthday" />
<gift name="Present" Value="Jeff's prezzy" />
</gifts>
</event>
</events>
</person>
<person name="Maisey">
<events>
<event name="Promotion">
<gifts>
<gift name="Cake" value="Well Done!" />
</gifts>
</event>
<event name="Birthday">
<gifts>
<gift name="Card" value="Happy Birthday" />
<gift name="Cake" value="Another Year Older!" />
</gifts>
</event>
</events>
</person>
</celebrations>
My current SQLXML looks like this:
SELECT (
SELECT (
SELECT T1.*
FOR XML path('')
,root('gifts')
,type
)
FROM #TempTable AS T1
FOR XML path('person')
,type
)
FOR XML path('persons')
Which is currently producing this:
<persons>
<person>
<gifts>
<name>Jeff</name>
<event>Birthday</event>
<gift>Card</gift>
<label>Happy Birthday</label>
</gifts>
</person>
<person>
<gifts>
<name>Jeff</name>
<event>Birthday</event>
<gift>Present</gift>
<label>Jeff`s prezzy</label>
</gifts>
</person>
<person>
<gifts>
<name>Maisey</name>
<event>Promotion</event>
<gift>Cake</gift>
<label>Well Done!</label>
</gifts>
</person>
<person>
<gifts>
<name>Maisey</name>
<event>Birthday</event>
<gift>Card</gift>
<label>Happy Birthday</label>
</gifts>
</person>
<person>
<gifts>
<name>Maisey</name>
<event>Birthday</event>
<gift>Cake</gift>
<label>Another Year Older!</label>
</gifts>
</person>
</persons>
How do I format it to look like the XML in the portion at the top of this post?
Try this, the magic is the correlated sub-query with GROUP BY:
DECLARE #TempTable TABLE
(
[name] VARCHAR(250),
[event] VARCHAR(250),
[gift] VARCHAR(250),
[label] VARCHAR(2500)
);
INSERT INTO #TempTable([name], [event], [gift], [label]) VALUES
('Jeff','Birthday','Card','Happy Birthday'),
('Jeff','Birthday','Present','Jeff`s prezzy'),
('Maisey','Promotion','Cake','Well Done!'),
('Maisey','Birthday','Card','Happy Birthday'),
('Maisey','Birthday','Cake','Another Year Older!')
SELECT t1.[Name] AS [#name]
,(
SELECT T2.[Event] AS [#name]
,(
SELECT T3.gift AS [#name], T3.label AS [#value]
FROM #TempTable T3
WHERE T1.[Name]=T3.[Name] AND T2.[event] = T3.[event]
GROUP BY T3.gift, T3.label
FOR XML PATH('gift'),ROOT('gifts'),TYPE
)
FROM #TempTable T2
WHERE T1.[Name]=T2.[Name]
GROUP BY T2.[event]
FOR XML PATH('event'),ROOT('events'),TYPE
)
FROM #TempTable AS T1
GROUP BY t1.[Name]
FOR XML PATH('person'),ROOT('celebrations'),TYPE;
The result
<celebrations>
<person name="Jeff">
<events>
<event name="Birthday">
<gifts>
<gift name="Card" value="Happy Birthday" />
<gift name="Present" value="Jeff`s prezzy" />
</gifts>
</event>
</events>
</person>
<person name="Maisey">
<events>
<event name="Birthday">
<gifts>
<gift name="Cake" value="Another Year Older!" />
<gift name="Card" value="Happy Birthday" />
</gifts>
</event>
<event name="Promotion">
<gifts>
<gift name="Cake" value="Well Done!" />
</gifts>
</event>
</events>
</person>
</celebrations>
I would like to update a table_A with new values for (AcresDist1, txtAcresDist1, txtAcresDist1Total) XML columns from a second table_B.
The column P_XML is of XML type. I know how to update a single column at once, but I would like to know how to update multiple columns in the XML using a single update statement. Thanks
SQL code:
UPDATE S
SET
P_XML.modify( N'replace value of (/FormValue/f1152_F1/Field[(id/text())[1]="AcresDist1"]/value/text())[1] with sql:column(''T.AcresDist1'')' )
, P_XML.modify( N'replace value of (/FormValue/f1152_F1/Field[(id/text())[1]="txtAcresDist1"]/value/text())[1] with sql:column(''T.txtAcresDist'')' )
, P_XML.modify( N'replace value of (/FormValue/f1152_F1/Field[(id/text())[1]="txtAcresDist1Total"]/value/text())[1] with sql:column(''T.txtAcresDist1Total'')' )
FROM
Table_A AS S
INNER JOIN
Table_B AS T ON s.P_NO = t.P_Number
AND s.FAC_RID = t.Fac_RID;
Here is the sample xml as requested. Thank you.
<FormValue>
<f1152>
<field>
<id>f1152_MainForm</id>
<value />
<tag />
<visible>true</visible>
<history>|09/28/2017 10:50:26 AM||</history>
<description />
<comment />
</field>
<field>
<id>txt_rdoCoverage</id>
<value>Development</value>
<tag />
<visible>false</visible>
<history>|09/28/2017 10:50:26 AM||</history>
<description />
<comment />
</field>
</f1152>
<f1152_F1>
<field>
<id>txtAcresDist1</id>
<value>1.2</value>
<tag />
<visible>false</visible>
<history>|09/28/2017 3:08:14 AM||</history>
<description />
<comment />
</field>
<field>
<id>txtAcresDist1Total</id>
<value>200</value>
<tag />
<visible>false</visible>
<history>|09/28/2017 3:08:14 AM||</history>
<description />
<comment />
</field>
</f1152_F1>
The following TSQL code is designed to emit data in XML Format. The following code:
SELECT l.wlst_Name [Name]
, pid.wpid_Number AS [Value]
, pid.wpid_IsPrimary AS [IsPrimary]
FROM dbo.tb_W_PhoneInternetData AS pid
INNER JOIN dbo.tb_W_Lists AS l ON pid.wpid_wlst_Type_fk = l.wlst_pk
ORDER BY l.wlst_Name, pid.wpid_IsPrimary DESC
FOR XML RAW('Data'),TYPE
returns the following data, which is OK.... however
<Data Name="Email" Value="kevin#myemail.com" IsPrimary="1" />
<Data Name="Fax" Value="21950121" IsPrimary="1" />
<Data Name="ID Number" Value="123435456m" IsPrimary="0" />
<Data Name="Mobile" Value="99977500" IsPrimary="1" />
<Data Name="Phone" Value="23977500" IsPrimary="1" />
<Data Name="Tax No" Value="737 0443 41" IsPrimary="0" />
<Data Name="Website" Value="asdf" IsPrimary="0" />
....but I need it the following format:
<Data Name="Email" IsPrimary="1">kevin#myemail.com</Data>
<Data Name="Fax" IsPrimary="1" >21950121</Data>
<Data Name="ID Number" IsPrimary="0" />123435456m</Data>
<Data Name="Mobile" IsPrimary="1" >99977500</Data>
<Data Name="Phone" IsPrimary="1" >23977500</Data>
<Data Name="Tax No" IsPrimary="0" >737 0443 41</Data>
<Data Name="Website" IsPrimary="0" >asdf</Data>
? What can I do ?
As #marc_s wrote - use FOR XML PATH. To get exactly result you may try the following:
CREATE TABLE #test(
Name VARCHAR(10),
Value VARCHAR(100),
IsPrimary BIT
)
INSERT INTO #test (Name, Value, IsPrimary) VALUES
('Email', 'kevin#myemail.com', 1),
('Fax', '21950121', 1),
('ID Number', '123435456m', 0),
('Mobile', '99977500', 1),
('Phone', '23977500', 1),
('Tax No', '737 0443 41', 0),
('Website', 'asdf', 0)
SELECT
'Data/#Name' = Name,
'Data/#IsPrimary' = IsPrimary,
'Data' = Value
FROM #test
FOR XML PATH(''), ROOT('All'), TYPE
DROP TABLE #test
-- Result
<All>
<Data Name="Email" IsPrimary="1">kevin#myemail.com</Data>
<Data Name="Fax" IsPrimary="1">21950121</Data>
<Data Name="ID Number" IsPrimary="0">123435456m</Data>
<Data Name="Mobile" IsPrimary="1">99977500</Data>
<Data Name="Phone" IsPrimary="1">23977500</Data>
<Data Name="Tax No" IsPrimary="0">737 0443 41</Data>
<Data Name="Website" IsPrimary="0">asdf</Data>
</All>
UPDATE: #Mikael Eriksson suggested star wildcard. Another version below:
SELECT
'#Name' = Name,
'#IsPrimary' = IsPrimary,
'*' = Value
FROM #test
FOR XML PATH('Data'), ROOT('All'), TYPE
You should be able to do this with FOR XML PATH - something like this:
SELECT
l.wlst_Name AS '#Name',
pid.wpid_IsPrimary AS '#IsPrimary',
pid.wpid_Number AS 'text()'
FROM
dbo.tb_W_PhoneInternetData AS pid
INNER JOIN
dbo.tb_W_Lists AS l ON pid.wpid_wlst_Type_fk = l.wlst_pk
ORDER BY
l.wlst_Name, pid.wpid_IsPrimary DESC
FOR XML PATH('Data'), ROOT('AllData')
Basically, what you want to use as attributes needs to be selected with a column alias that starts with a # sign.
Update: I updated my response - what I had been looking for (and not able to find right away) is the ... AS 'text()' which basically produces the same output (value of the column is output as literal text - without any XML element open/end tags around it) as the "wildcard" character that #MikaelEriksson mentioned.