0

我将 XML 传递给存储过程以进行插入。XML 包含一些信息,例如产品规格,它是一个字符串。

以下是 XML 的样例:

<?xml version="1.0"?>
<Details>
    <item Unit="PilotApp.DataAccessObject.DTO.Unit" 
          PSASysCommon="" 
          ProductModel="PilotApp.DataAccessObject.DTO.ProductModel" 
          Product="PilotSmithApp.DataAccessObject.DTO.Product" 
          SpecTag="62793f05-25ab-41b5-a081-f6c542f1f7cd" 
          Rate="100" UnitCode="1" Qty="1" 
          ProductSpec="Pilot Cone Blender Model No. Pilot PCB - 10 , volume of vessel -30 Ltr , handling capacity per batch by weight - 10 Kg and by volume - 20 Ltr. with motor - 0.25 HP/3 ph. Crompton make or equivalent , feeding door , discharge butterfly valve and safety guard .Material of construction of contact stainless steel (AISI) 304 and frame in carbon steel . Purpose : For blending dry powder and granules" 
          ProductModelID="10c0b51b-7799-4597-a4af-7c3fd431353b" 
          ProductID="15745d53-8219-431e-a0e3-0d319abf132d" 
          EnquiryID="00f9436c-ed2a-442c-b333-16348b0d8c33" 
          ID="e6812788-e67e-4874-bf80-87b39579a837"/>
</Details>

在此产品规格部分中,添加了用途 部分。所以,我想将它作为新行插入或显示为新行,我想使用 T-SQL

这是将 XML 插入临时表的代码

DECLARE @temp TABLE(
ID UNIQUEIDENTIFIER,
EnquiryID UNIQUEIDENTIFIER,
ProductID UNIQUEIDENTIFIER,
ProductModelID UNIQUEIDENTIFIER,
ProductSpec NVARCHAR(MAX),
Qty DECIMAL(18,2),
Rate DECIMAL(18,2),
UnitCode INT,
SpecTag UNIQUEIDENTIFIER,
IsProcessed bit,
tmpID UNIQUEIDENTIFIER
);
------------parse from xml to temptable ----


        INSERT INTO @temp(ID,EnquiryID,ProductID,ProductModelID,
        ProductSpec,Qty,Rate,UnitCode,SpecTag,IsProcessed,tmpID)
        SELECT T.ID,T.EnquiryID,T.ProductID,T.ProductModelID,replace(replace(replace(replace(T.ProductSpec,'&quot;','"'),'&amp;','&'),'&lt;','<'),'&gt;','>') AS ProductSpec,
        T.Qty,T.Rate,T.UnitCode,
        -----modified on 14-May-2018 added field SpecTag in EnquiryDetail by Thomson
        CASE WHEN T.SpecTag=CAST(CAST(0 AS BINARY) AS UNIQUEIDENTIFIER) THEN NEWID() ELSE T.SpecTag END,
        T.IsProcessed,T.tmpID FROM
        (SELECT [xmlData].[Col].value('./@ID', 'UNIQUEIDENTIFIER') as ID,
        [xmlData].[Col].value('./@EnquiryID', 'UNIQUEIDENTIFIER') as EnquiryID,
        [xmlData].[Col].value('./@ProductID', 'UNIQUEIDENTIFIER') as ProductID,
        [xmlData].[Col].value('./@ProductModelID', 'UNIQUEIDENTIFIER') as ProductModelID,
        [xmlData].[Col].value('./@ProductSpec', 'NVARCHAR(MAX)') as ProductSpec,
        [xmlData].[Col].value('./@Qty','DECIMAL(18,2)')as Qty,
        [xmlData].[Col].value('./@Rate','DECIMAL(18,2)')as Rate,
        [xmlData].[Col].value('./@UnitCode','INT')as UnitCode,
        [xmlData].[col].value('./@SpecTag','UNIQUEIDENTIFIER') AS SpecTag,
        0 as IsProcessed,
        newid() as tmpID
        from @DetailXML.nodes('/Details/item') as [xmlData]([Col])) T
4

2 回答 2

1

试试这个来找出如何提取嵌套在你的 XML 中的数据:

DECLARE @xml XML=
'<?xml version="1.0"?>
<Details>
    <item Unit="PilotApp.DataAccessObject.DTO.Unit" 
          PSASysCommon="" 
          ProductModel="PilotApp.DataAccessObject.DTO.ProductModel" 
          Product="PilotSmithApp.DataAccessObject.DTO.Product" 
          SpecTag="62793f05-25ab-41b5-a081-f6c542f1f7cd" 
          Rate="100" UnitCode="1" Qty="1" 
          ProductSpec="Pilot Cone Blender Model No. Pilot PCB - 10 , volume of vessel -30 Ltr , handling capacity per batch by weight - 10 Kg and by volume - 20 Ltr. with motor - 0.25 HP/3 ph. Crompton make or equivalent , feeding door , discharge butterfly valve and safety guard .Material of construction of contact stainless steel (AISI) 304 and frame in carbon steel . Purpose : For blending dry powder and granules" 
          ProductModelID="10c0b51b-7799-4597-a4af-7c3fd431353b" 
          ProductID="15745d53-8219-431e-a0e3-0d319abf132d" 
          EnquiryID="00f9436c-ed2a-442c-b333-16348b0d8c33" 
          ID="e6812788-e67e-4874-bf80-87b39579a837"/>
</Details>';

SELECT itm.value('@Unit','nvarchar(max)') AS Unit
      ,itm.value('@PSASysCommon','nvarchar(max)') AS PSASysCommon
      ,itm.value('@Product','nvarchar(max)') AS Product
      ,itm.value('@SpecTag','uniqueidentifier') AS SpecTag
      ,itm.value('@Rate','int') AS Rate
      ,itm.value('@UnitCode','int') AS UnitCode
      ,itm.value('@Qty','int') AS Qty
      ,itm.value('@ProductSpec','nvarchar(max)') AS ProductSpec
      ,itm.value('@ProductModelID','uniqueidentifier') AS ProductModelID
      ,itm.value('@ProductID','uniqueidentifier') AS ProductID
      ,itm.value('@ID','uniqueidentifier') AS ID
FROM @xml.nodes('/Details/item') A(itm);

我的方法假设,<item><Details>.

只是一些解释:该<item>元素是一个自闭合元素,所有数据都放在属性中。这是一个非常容易查询的表格。对你有益...

顺便说一句:最好完全避免<?xml blah?>- 声明。在 SQL-Server 中,这个声明是无用的,并且会干扰编码......

更新

一个增强的查询来解析行中的规范并提取Purpose

SELECT itm.value('@Unit','nvarchar(max)') AS Unit
      ,itm.value('@PSASysCommon','nvarchar(max)') AS PSASysCommon
      ,itm.value('@Product','nvarchar(max)') AS Product
      ,itm.value('@SpecTag','uniqueidentifier') AS SpecTag
      ,itm.value('@Rate','int') AS Rate
      ,itm.value('@UnitCode','int') AS UnitCode
      ,itm.value('@Qty','int') AS Qty
      ,itm.value('@ProductSpec','nvarchar(max)') AS ProductSpec
      ,itm.value('@ProductModelID','uniqueidentifier') AS ProductModelID
      ,itm.value('@ProductID','uniqueidentifier') AS ProductID
      ,itm.value('@ID','uniqueidentifier') AS ID
      ,LTRIM(RTRIM(ProductSpecLine.value('text()[1]','nvarchar(max)'))) AS ProductSpecLine_Text
      ,Purpose
FROM @xml.nodes('/Details/item') A(itm)
OUTER APPLY(SELECT CAST('<x>' + REPLACE((SELECT itm.value('@ProductSpec','nvarchar(max)') AS [*] FOR XML PATH('')),',','</x><x>') + '</x>' AS XML)) B(x)
OUTER APPLY B.x.nodes('/x') C(ProductSpecLine)
OUTER APPLY (SELECT CASE WHEN CHARINDEX('Purpose : ',ProductSpecLine.value('text()[1]','nvarchar(max)'))>0 
                         THEN SUBSTRING(ProductSpecLine.value('text()[1]','nvarchar(max)'),CHARINDEX('Purpose : ',ProductSpecLine.value('text()[1]','nvarchar(max)')),1000)
                    END) D(Purpose);
于 2018-11-06T08:10:12.320 回答
1

以下是解决此问题的步骤。

  1. 首先从 ProductSpec XML 标记中获取整个字符串作为列名“ProductSpec”。

  2. 从 ProductSpec 中获取子字符串,其中子字符串从新列中的目的开始为“ProductSpecPurpose”。

  3. 根据您的需要在您提取的字符串中附加 char(10) 或 char(13) 。例如 char(10) + ProductSpecPurpose。

  4. 合并在步骤 1 和 2 中创建的两列。

  5. 保存。

PS:我没有直接写解决方案,至少你可以尝试不同的sql函数并了解更多。因为我相信自己学习而不是用勺子喂食。试试看,如果你无法弄清楚。做评论然后我会写整个sql答案。

于 2018-11-06T06:05:15.937 回答