我有XML格式数据,我将从.net应用程序传递。
在SQL Server存储过程中,此数据作为XML参数传入。我想阅读并保存所需表格中的数据,例如TblOrder
和TblItem
。
在XML中,会有多个订单。每个订单都包含一个或多个项目。
需要实施操作的结构:
<?xml version="1.0" encoding="UTF-8"?>
<Orders>
<Order>
<B2>B2**ABIJ**0000884443**PP</B2>
<CreateBy null="true" />
<CreateDate>/Date(1485150414358)/</CreateDate>
<CurrencyId>1</CurrencyId>
<CustomerId>13</CustomerId>
<DeliveryAddress>LIBERTY PRESS LLC</DeliveryAddress>
<DeliveryCity>SPRINGVILLE UT 84663</DeliveryCity>
<DeliveryCityId>0</DeliveryCityId>
<DeliveryDate>/Date(1478750400000)/</DeliveryDate>
<DeliveryId>14</DeliveryId>
<DeliveryState>UT</DeliveryState>
<DeliveryStateId>16</DeliveryStateId>
<DeliveryType>Delivery</DeliveryType>
<EquipmentId>4</EquipmentId>
<Items>
<Item>
<CSA>false</CSA>
<CTPAT>false</CTPAT>
<CommodityItem>General Freight</CommodityItem>
<CommodityItemId>0</CommodityItemId>
<CustCommodityItem null="true" />
<FAST>false</FAST>
<Hazmat>false</Hazmat>
<Height null="true" />
<IsActive>false</IsActive>
<ItemId>0</ItemId>
<ItemName>Item A</ItemName>
<Length null="true" />
<Make null="true" />
<Mass null="true" />
<MassUnit null="true" />
<Model null="true" />
<OrderId>0</OrderId>
<PIP>false</PIP>
<PilotCar>false</PilotCar>
<ReeferTemp null="true" />
<Tarp>false</Tarp>
<TrailerType null="true" />
<TruckType null="true" />
<VIN null="true" />
<Width null="true" />
<Year null="true" />
</Item>
</Items>
<L11>L11*SYL884443*BM</L11>
<LastUpdate>/Date(1485150414358)/</LastUpdate>
</Order>
<Order>
...
<Items>
<Item>
...
</Item>
</Order>
</Orders>
我想要实现的步骤是:
TblOrder
和TblItem
表格通过以下文章:
我的想法是访问第一级(在我的情况下,订单顺序)。 继续问题,访问第二级,这将再次成为一个集合(在我的案例中是订单项目的项目)。
提前感谢您的支持
答案 0 :(得分:1)
您有两种方法:
从我提出的问题来看,您更愿意将其作为XML参数传递给存储过程。有一些事情要知道:
C#在内部使用 16位unicode ,SQL Server的XML也是如此。但只要包含encoding="UTF-8"
,您就无法将此unicode字符串强制转换为XML ...您可以将其作为VARCHAR(MAX)
(不是NVARCHAR(MAX)
!)传递给您,但这可能会如果涉及特殊字符,会引发麻烦。最好的是,完全删除第一行(<?xml ...?>
声明)。
您的XML未正确创建。这是你掌控的吗?如果你包含null="true"
(通常不需要!),你应该使用xsi
- 命名空间。 XML中的日期/时间值应为ISO8601。您的值(如/Date(1485150414358)/
)不是SQL Server能够直接投射的格式......
尽管如此,我看到了多个<Order>
- 元素和多个<Item>
- 元素。您可以按如下方式阅读它们:
DECLARE @xml XML=
N'<Orders>
<Order>
<B2>B2**ABIJ**0000884443**PP</B2>
<CreateBy null="true" />
<CreateDate>/Date(1485150414358)/</CreateDate>
<CurrencyId>1</CurrencyId>
<CustomerId>13</CustomerId>
<DeliveryAddress>LIBERTY PRESS LLC</DeliveryAddress>
<DeliveryCity>SPRINGVILLE UT 84663</DeliveryCity>
<DeliveryCityId>0</DeliveryCityId>
<DeliveryDate>/Date(1478750400000)/</DeliveryDate>
<DeliveryId>14</DeliveryId>
<DeliveryState>UT</DeliveryState>
<DeliveryStateId>16</DeliveryStateId>
<DeliveryType>Delivery</DeliveryType>
<EquipmentId>4</EquipmentId>
<Items>
<Item>
<CSA>false</CSA>
<CTPAT>false</CTPAT>
<CommodityItem>General Freight</CommodityItem>
<CommodityItemId>0</CommodityItemId>
<CustCommodityItem null="true" />
<FAST>false</FAST>
<Hazmat>false</Hazmat>
<Height null="true" />
<IsActive>false</IsActive>
<ItemId>0</ItemId>
<ItemName>Item A</ItemName>
<Length null="true" />
<Make null="true" />
<Mass null="true" />
<MassUnit null="true" />
<Model null="true" />
<OrderId>0</OrderId>
<PIP>false</PIP>
<PilotCar>false</PilotCar>
<ReeferTemp null="true" />
<Tarp>false</Tarp>
<TrailerType null="true" />
<TruckType null="true" />
<VIN null="true" />
<Width null="true" />
<Year null="true" />
</Item>
</Items>
<L11>L11*SYL884443*BM</L11>
<LastUpdate>/Date(1485150414358)/</LastUpdate>
</Order>
</Orders>';
- 查询
SELECT --elements of Order
o.value(N'(B2)[1]',N'nvarchar(max)') AS B2
--very strange date-format...
,o.value(N'(CreateDate)[1]',N'nvarchar(max)') AS CreateDate
--typed INT
,o.value(N'(CurrencyId)[1]',N'int') AS CurrencyId
--more like this
--elements of Item
,i.value(N'(CSA)[1]',N'nvarchar(max)') AS CSA
--There's no need for *null="true"*
--Query the "/text()" and the empty element will be NULL
,CASE WHEN i.value(N'(CustCommodityItem/@null)[1]',N'nvarchar(max)')=N'true' THEN NULL ELSE i.value(N'(CustCommodityItem)[1]',N'nvarchar(max)') END AS CustCommodityItem_complicated
,i.value(N'(CustCommodityItem)[1]',N'nvarchar(max)') AS CustCommodityItem_empty
,i.value(N'(CustCommodityItem/text())[1]',N'nvarchar(max)') AS CustCommodityItem_null
FROM @xml.nodes(N'/Orders/Order') AS A(o)
OUTER APPLY o.nodes(N'Items/Item') AS B(i)