2017-01-23 11 views
0

.netアプリケーションから渡すXML形式のデータがあります。XMLマルチレベルデータをパラメータとして渡してストアドプロシージャで使用する

SQL Serverストアドプロシージャでは、このデータはXMLパラメータとして渡されます。私は、必要なテーブル、例えばTblOrderTblItemにデータを読み込んで保存したいと思います。

XMLでは、複数の注文があります。各注文には1つまたは複数の明細が含まれています。

実装する必要のある操作上の構造:私が達成したい

<?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> 

手順は次のとおりです:.NETアプリケーションから渡されたストアドプロシージャから

  • 読むのXMLパラメータ。
  • XMLをループして記事を通って行くTblOrderTblItemテーブル

にデータを保存するには、次のとおりです。私はアイデアを得た

非常に最初のレベルにアクセスしてください(私の場合はOrder of Order)。 2番目のレベルにアクセスする際に問題が発生しましたが、これもコレクションになります(私の場合、Order of Itemsアイテム)。ご支援

+0

私はあなたの質問はあなたがC#でそれを行うことができたときにSQLでXMLを解析したいのはなぜ –

+0

が何であるかわからないんだけど? – jdweng

+0

私は、.NETアプリケーションからパラメータとしてXMLデータを渡す必要があるschenerioを持っています。 – UJS

答えて

1

を事前に

ありがとうございますが、二つのアプローチがあります:あなたはストアドプロシージャにあるとして、XML を渡し、T-SQL内のすべてのハードワークを行うことができます

  • C#でXMLを細断し、適切なデータオブジェクトを埋め、古典的なデータストレージを使用できます。

あなたの質問から、XMLパラメータとしてストアドプロシージャに渡すことをお勧めします。知っているいくつかのものがあります。

  • C#が内部16ビットユニコードを使用していますので、SQL ServerのXMLを行います。しかし、encoding="UTF-8"が含まれている限り、このユニコード文字列をXMLにキャストすることはできません... VARCHAR(MAX)NVARCHAR(MAX)ではなく!)として渡すことができますが、これはセパルシャル文字が関わっている場合に問題につながります。最善の方法は、最初の行(<?xml ...?>宣言)を完全に削除することでした。

  • XMLが正しく作成されていません。これはあなたの支配下にありますか? null="true"を含めると(通常は必要ありません)、xsi -n名前空間でこれを行う必要があります。日付と時刻の値に、XMLはISO8601である必要があります。あなたの値(/Date(1485150414358)/のような)はフォーマットではありませんSQL Serverは直接キャストすることができます...

それでも私は、マルチ<Order> -elementsとマルチ<Item> -elementsを参照してください。次のようにそれらを読むことができる:

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>'; 

を--theクエリ

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) 
+0

Thanks @ Shnugo、それは私のために働いています。 – UJS

+0

@UJS検索エンジンを使って "SQL Server XML"を検索すれば、たくさんのチュートリアルが見つかります。 1つの良いサイト - 少なくとも人々はそう言っています - www.stackoverflow.comでなければなりません。あなたがユーザープロファイル(* Shnugo *と呼ばれると思います)にアクセスすると、 – Shnugo

関連する問題