[英]How do I select data from a XML column on SQL Server?
How do I select data from a XML column in a SQL Server table in SQL Server Management Studio?如何从 SQL 服务器表中的 SQL 服务器表中的 XML 列中的 select 数据?
I would like to get this result:我想得到这个结果:
orderDdate createdBby orderNo currency taxation inv customer mail
2019-09-05 storefront 000001 USD gross 0099999 Jonh Smith JonhSmith@gmail.com
<orders xmlns="www address">
<order>
<order-date>2019-09-05</order-date>
<created-by>storefront</created-by>
<original-order-no>000001</original-order-no>
<currency>USD</currency>
<taxation>gross</taxation>
<invoice-no>0099999</invoice-no>
<customer>
<customer-name>Jonh Smith</customer-name>
<customer-email>JonhSmith@gmail.com</customer-email>
</customer>
<notes>
<note>
<created-by>system</created-by>
<creation-date>2019-09-06T07:05:03.000Z</creation-date>
<subject>Fulfilment Status</subject>
<text>The order fulfilment status was changed from '01' to '02'.</text>
</note>
<note>
<created-by>system</created-by>
<creation-date>2019-09-06T07:05:03.000Z</creation-date>
<subject>Fulfilment Status</subject>
<text>The order fulfilment status was changed from '02' to '03'.</text>
</note>
<note>
<created-by>system</created-by>
<creation-date>2019-09-06T07:05:03.000Z</creation-date>
<subject>Fulfilment Status</subject>
<text>The order fulfilment status was changed from '03' to '03'.</text>
</note>
</notes>
<product-lineitems>
<product-lineitem>
<product-id>0001</product-id>
<quantity unit="BOX">1.0</quantity>
<tax-rate>0.23</tax-rate>
</product-lineitem>
<product-lineitem>
<product-id>0002</product-id>
<quantity unit="PCS">1.0</quantity>
<tax-rate>0.23</tax-rate>
</product-lineitem>
</product-lineitems>
</order>
I have the last problem (i hope);)我有最后一个问题(我希望);)
How to return data from product-lineitems.如何从 product-lineitems 返回数据。 I mean: Quantity, Quantity-unit我的意思是:数量,数量单位
Im trying like that: But it's return duplicate rows:(我正在尝试这样:但它返回重复的行:(
WITH XMLNAMESPACES(DEFAULT N'www address')
SELECT
o.value(N'(current-order-no/text())[1]',N'varchar(10)') AS OrderNo
,n.value(N'(quantity/text())[1]',N'varchar(10)') AS Qty
,u.value(N'@unit',N'varchar(10)') AS Unit
FROM
dbSupply.dbo.MyXmlTable t
CROSS APPLY
t.XMLData.nodes(N'/orders/order') A(o)
OUTER APPLY
A.o.nodes(N'product-lineitems/product-lineitem') B(n)
OUTER APPLY
A.o.nodes(N'product-lineitems/product-lineitem/quantity') C(u)
'It looks like your post is mostly code; '看起来你的帖子主要是代码; please add some more details' 'It looks like your post is mostly code;请添加更多详细信息' '看起来您的帖子主要是代码; please add some more details' 'It looks like your post is mostly code;请添加更多详细信息' '看起来您的帖子主要是代码; please add some more details'请添加更多详细信息'
You can try it like this:你可以这样尝试:
DECLARE @mockupTable TABLE(ID INT IDENTITY, YourXml XML);
INSERT INTO @mockupTable VALUES
(N'<orders xmlns="www address">
<order order-no="000001">
<order-date>2019-09-05</order-date>
<created-by>storefront</created-by>
<original-order-no>000001</original-order-no>
<currency>USD</currency>
<taxation>gross</taxation>
<invoice-no>0099999</invoice-no>
<customer>
<customer-name>Jonh Smith</customer-name>
<customer-email>JonhSmith@gmail.com</customer-email>
</customer>
</order>
</orders>');
WITH XMLNAMESPACES(DEFAULT N'www address')
SELECT o.value(N'@order-no',N'varchar(10)') AS OrderNo
,o.value(N'(order-date/text())[1]',N'date') AS OrderDate
,o.value(N'(created-by/text())[1]',N'varchar(100)') AS CreatedBy
,o.value(N'(original-order-no/text())[1]',N'varchar(10)') AS OriginalOrderNo
,o.value(N'(currency/text())[1]',N'varchar(10)') AS Currency
,o.value(N'(taxation/text())[1]',N'varchar(10)') AS Taxation
,o.value(N'(invoice-no/text())[1]',N'varchar(10)') AS InvoiceNo
,o.value(N'(customer/customer-name/text())[1]',N'varchar(100)') AS CustomerName
,o.value(N'(customer/customer-email/text())[1]',N'varchar(100)') AS CustomerEMail
FROM @mockupTable t
CROSS APPLY t.YourXml.nodes(N'/orders/order') A(o);
Be aware of the need to declare your (default) name space correctly.请注意需要正确声明您的(默认)名称空间。 I used .nodes()
because "orders" sounds like plural.我使用.nodes()
因为“orders”听起来像复数。 Your sample includes just one order, but there might be more...您的样品仅包含一份订单,但可能还有更多……
In any case of 1:n
relationship (many nodes related to one partent node), you need .nodes()
in order to get each fragment as a separate row:在任何1:n
关系的情况下(许多节点与一个子节点相关),您需要.nodes()
才能将每个片段作为单独的行:
WITH XMLNAMESPACES(DEFAULT N'www address')
SELECT o.value(N'@order-no',N'varchar(10)') AS OrderNo
,o.value(N'(order-date/text())[1]',N'date') AS OrderDate
,o.value(N'(created-by/text())[1]',N'varchar(100)') AS CreatedBy
,o.value(N'(original-order-no/text())[1]',N'varchar(10)') AS OriginalOrderNo
,o.value(N'(currency/text())[1]',N'varchar(10)') AS Currency
,o.value(N'(taxation/text())[1]',N'varchar(10)') AS Taxation
,o.value(N'(invoice-no/text())[1]',N'varchar(10)') AS InvoiceNo
,o.value(N'(customer/customer-name/text())[1]',N'varchar(100)') AS CustomerName
,o.value(N'(customer/customer-email/text())[1]',N'varchar(100)') AS CustomerEMail
,n.value(N'(created-by/text())[1]',N'nvarchar(100)') AS Note_CreatedBy
,n.value(N'(creation-date/text())[1]',N'datetime') AS Note_CreatedBy
,n.value(N'(subject/text())[1]',N'nvarchar(100)') AS Note_CreatedBy
,n.value(N'(text/text())[1]',N'nvarchar(1000)') AS Note_CreatedBy
FROM @mockupTable t
CROSS APPLY t.YourXml.nodes(N'/orders/order') A(o)
OUTER APPLY A.o.nodes(N'notes/note') B(n);
The last line will pick the current order and pass it into .nodes()
.最后一行将选择当前订单并将其传递给.nodes()
。 This will return a derived set with one row per <note>
.这将返回一个派生集,每个<note>
有一行。
You can use OPENROWSET您可以使用OPENROWSET
CREATE DATABASE MyXmlDataBase
GO
USE MyXmlDataBase
GO
CREATE TABLE MyXmlTable
(
Id INT IDENTITY PRIMARY KEY,
Name NVARCHAR(50),
XMLData XML
)
INSERT INTO MyXmlTable(Name, XMLData)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE()
FROM OPENROWSET(BULK 'D:\MyXmlFileOnDisk.xml', SINGLE_BLOB) AS x;
SELECT * FROM MyXmlTable
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.