I have a table in SQL Server and I am putting the values of the result set from the table into XML like this:
select
lAccountID,
sName,
sAge
from
AccountDVDetails
where
laccountID = 10
for xml raw ('Values'), ROOT ('Accounts'), ELEMENTS
This query gives me XML like
<Accounts>
<Values>
<lAccountID>10</lAccountID>
<sName>A</sName>
<sAge>21</sAge>
</Values>
<Values>
<lAccountID>10</lAccountID>
<sName>B</sName>
<sAge>22</sAge>
</Values>
<Values>
<lAccountID>10</lAccountID>
<sName>C</sName>
<sAge>23</sAge>
</Values>
</Accounts>
Now I want to store this XML with lAccountId in a temporary table #tmpAccount like
lAccountId XMLValue
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
10 <Accounts><Values><lAccountID>10</lAccountID><sName>A</sName><sAge>21</sAge></Values><Values><lAccountID>10</lAccountID><sName>B</sName><sAge>22</sAge></Values><Values><lAccountID>10</lAccountID><sName>C</sName><sAge>23</sAge></Values></Accounts>
How can I achieve this? I have tried putting the XML into string variable but the XML gets truncated to a certain limit.
Any help will be deeply appreciated. Thanks.
Try this for a nested, hierarchical XML for many Accounts
First I declare some table variables to mock-up a test scenario. I assume, that there is a parent table with accounts:
DECLARE #dummyAccount TABLE(lAccountID INT IDENTITY,SomeData VARCHAR(100));
DECLARE #dummyAccountDetail TABLE(lAccountDetail INT IDENTITY,lAccountID INT,sName VARCHAR(100),sAge INT);--do not store the age as int but the DoB!!!
INSERT INTO #dummyAccount VALUES('Account 1'),('Account 2');
INSERT INTO #dummyAccountDetail VALUES(1,'Jane',20),(1,'John',30)
,(2,'Tim',40),(2,'Tom',50);
The query will list the accounts as first level (I added some descibing attributes just to show the principles, but you can easily let them away. The sub-select will create an XML for each account separately.
SELECT A.lAccountID
,A.SomeData
,(
SELECT D.lAccountID
,D.sName
,D.sAge
FROM #dummyAccountDetail AS D
WHERE D.lAccountID=A.lAccountID
FOR XML PATH('Values'),ROOT('Accounts'),TYPE
)
FROM #dummyAccount AS A
You can easily create the table #tmpAccount just with
SELECT ...
INTO #tmpAccount
FROM ...
...or, if it exists already, just use
INSERT INTO #tmpAccount
SELECT ...
Check This.
select distinct
(
select
lAccountID,
sName,
sAge
from
AccountDVDetails
where
laccountID = 10
for xml raw ('Values'), ROOT ('Accounts'), ELEMENTS
)as XMLValue
,lAccountID into #tmpAccount from AccountDVDetails
where
laccountID = 10
select * from #tmpAccount
Related
I have very little experience with SQL Server. Here is what I am trying to accomplish:
I have a table with many rows. Every row contains a column named "Config". The data stored in the Config column is of the xml type. The xml structure looks like this:
<root>
<path1>
<path2>
<path3>true</path3>
</path2>
</path1>
</root>
I am trying to go through every row in the table and find the percentage of true to false values of <path3>.
I looked at some SQL documentation and tried to use the value() function I am having difficulties extracting the XML data from the column:
select Config.value('(/root/path1/path2/path3)[1]','nvarchar(max)') from [MyDB].[dbo].[MyTable]
Here is the result of my query:
I would like to query and extract data from the XML "Config" column of my table and aggregate that data into columns.
You need to specify namespaces in the query when xml is built with namespaces. For example
CREATE TABLE tbl (Config xml);
INSERT INTO tbl (Config)
VALUES ('<root xmlns="abc">
<path1>
<path2>
<path3>true</path3>
</path2>
</path1>
</root>') ;
Then
with xmlnamespaces (DEFAULT 'abc')
select Config.value('(/root/path1/path2/path3)[1]','nvarchar(max)') path3Txt
from tbl;
or explicit specification
with xmlnamespaces ('abc' as x)
select Config.value('(/x:root/x:path1/x:path2/x:path3)[1]','nvarchar(max)') path3Txt
from tbl;
You would need to use CROSS APPLY. Check it out.
SQL
-- DDL and sample data population, start
DECLARE #tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, [Config] XML);
INSERT INTO #tbl
VALUES (N'<root>
<path1>
<path2>
<path3>true</path3>
</path2>
</path1>
</root>')
, (N'<root>
<path1>
<path2>
<path3>false</path3>
</path2>
</path1>
</root>');
-- DDL and sample data population, end
;WITH rs AS
(
SELECT ID
, col.value('(./text())[1]','VARCHAR(20)') AS Result
FROM #tbl tbl
CROSS APPLY tbl.[Config].nodes('/root/path1/path2/path3') AS tab(col)
)
SELECT * FROM rs;
I have a simple SQL table with Values "Alpha", "Bravo" and "Charlie".
I Need to get result as displayed. The data within transaction: type, date, etc. are static and should be part of the select Statement.
I think this can be done using
SELECT ... for XML
But don't know how?
CREATE TABLE [dbo].[SampleTable]([ID_extern] [varchar](50) NULL)
INSERT INTO SampleTable VALUES ('Alpha')
INSERT INTO SampleTable VALUES ('Bravo')
INSERT INTO SampleTable VALUES ('Charlie')
INSERT INTO SampleTable VALUES ('Delta')
Here is a little kick-start for you
Example
Select [transaction/#type]='import_serial_number'
,[transaction/#date]='123459'
,[transaction/#vaultname]='Type in the name of the vault here'
,[transaction/serial_number/#name] = 'SampleAppendSerialNo'
,[transaction/serial_number/#mode] = 'append'
,[transaction/serial_number] = (
Select [serno_item/#item_counter] = row_number() over (order by ID_extern)
,[serno_item/#serno_item] = ID_extern
From SampleTable
For XML Path (''),TYPE
)
For XML Path('transactions'),Root('xml')
Returns
<xml>
<transactions>
<transaction type="import_serial_number" date="123459" vaultname="Type in the name of the vault here">
<serial_number name="SampleAppendSerialNo" mode="append">
<serno_item item_counter="1" serno_item="Alpha" />
<serno_item item_counter="2" serno_item="Bravo" />
<serno_item item_counter="3" serno_item="Charlie" />
<serno_item item_counter="4" serno_item="Delta" />
</serial_number>
</transaction>
</transactions>
</xml>
Where a column value goes in the XML is determined by a path in an alias. Use # for attributes. To get the ordinals you can use row_number().
Something like
SELECT row_number() OVER (ORDER BY id_extern) "serno_item/#item_counter",
id_extern "serno_item/#item_value"
FROM simple
FOR XML PATH ('');
gives you the inner part of the XML. You can either try nested queries or use string concatenation (concat()) to prepend/append the outer parts like in the following.
SELECT convert(xml, concat('<serial_number type="">',
(SELECT row_number() OVER (ORDER BY id_extern) "serno_item/#item_counter",
id_extern "serno_item/#item_value"
FROM simple
FOR XML PATH ('')),
'</serial_number>'));
(I'm not going to type all that stuff off of your screen shot, so this is just exemplary.)
Ideally, I would like a XML file that looks something like below, however so far my query does not generate the tag for OrderRequests, but only OrderRequest. Below is the query I have used and the XML that needs to be generated.
Query:
declare #xml XML;
declare #RequestFileHeader table
(
ClientCode varchar(10),
CreateTime varchar(40),
BatchNumber int
);
insert into #RequestFileHeader values('CMG','2013-09-16T00:20:13.7306775-07:00',
CAST(RAND() * 1000000 AS INT) )
select RequestFileHeader.*,
OrderRequest.TransactionTime,
(OrderRequest.ReferenceNumber -1000000+ CAST(RAND() *1000000 AS INT))
ReferenceNumber,
'False' as IsRush, ShippingAddress.*
from
#RequestFileHeader RequestFileHeader,
RbcRequest OrderRequest,
RbcOrderShippingAddress ShippingAddress-- , RbcRequest OrderRequests
where (ShippingAddress.RequestId = OrderRequest.RequestId)
for xml AUTO , root('TransactionRequest'), Elements
GO
XML:
<OrderRequests>
<OrderRequest>
<ReferenceNumber>647433081</ReferenceNumber>
<TransactionTime>2014-04-07T04:35:00</TransactionTime>
<IsRush>false</IsRush>
<ShippingAddress>
<Name>ROGER RAI</Name>
<Address1>18855 54A AVE</Address1>
<Address2 />
<Address3 />
<City>SURREY</City>
<Province>BC</Province>
<PostalCode>V3S6R4</PostalCode>
<HomePhone>6046008564</HomePhone>
<BusinessPhone>6047247883</BusinessPhone>
</ShippingAddress>
<ProgramType>AV</ProgramType>
<Comments />
<Items>
<Item>
<Sku>CC03327-SLV</Sku>
<ProductCode>AA1346</ProductCode>
<Quantity>1</Quantity>
</Item>
</Items>
</OrderRequest>
Embed the query you already have in a query that creates the root node. You also need to add the type directive to your existing query.
select (
-- Replace this with your existing query.
select *
from T
for xml auto, root('OrderRequest'), elements, type
)
for xml path('OrderRequests')
I have a table where a column contains XML data. Now i want to retrieve those xml data with restriction of nodes. Kindly see the following example for more explanation on my scenario,
declare #table table (id int, xmlfield xml) insert into #table select 1,'<Root xmlns="">
<Sample>
<Issue>
<Level>one</Level>
<Descp>First Example</Descp>
</Issue>
<Issue>
<Level>two</Level>
<Descp>Second Example</Descp>
</Issue>
</Sample> </Root>'
select * from #table
Now i need the following result set
Id XMLfield
1 first example
ie, for the selected level,i need the decription for it. More clearly, the node should be restricted for <level>one</level>
(need: What is the description for level one ?)
thanks in advance
Have a look at the xml Data Type Methods
select id,
xmlfield.value('(//Issue[Level = "one"]/Descp/text())[1]', 'varchar(100)') as XMLField
from #table
The XQuery you're looking for is
//Issue[Level = "one"]/Descp/data()
<suggestions>
<suggestion>
<description>plate.</description>
</suggestion>
<suggestion>
<description>snack.</description>
</suggestion>
</suggestions>
DECLARE #Suggestions TABLE (
[Description] VARCHAR(800)
)
I have above xml in a XML type varible in my stored procedure
how can i insert each text between description tags
in to the table #Suggestions
Try this:
DECLARE #input XML = '<suggestions>
<suggestion>
<description>plate.</description>
</suggestion>
<suggestion>
<description>snack.</description>
</suggestion>
</suggestions>'
DECLARE #Suggestions TABLE ([Description] VARCHAR(800))
INSERT INTO #Suggestions
SELECT
Sugg.value('(description)[1]', 'varchar(800)')
FROM
#input.nodes('/suggestions/suggestion') AS Tbl(Sugg)
SELECT * FROM #Suggestions
The #input.nodes() expression basically turns each <suggestion> node into a row in the "pseudo" table called Tbl(Sugg). From those "rows" (each basically another XML fragment), you then select out the value you're interested in - here the contents of the <description> XML element inside that XML fragment.
You can use LINQ-to-XML to get all suggestions, then you can insert that data into the table.