2017-01-19 14 views
4

私はこのサイトを長い間使用していましたが、何度もさまざまな問題を解決するのに役立ちました。 今回は私が立ち往生しています。私はms - sqlのテーブルには、1つのような複雑なXMLをインポートしようとします。OPENXML import xml to ms sql-namespace

<?xml version='1.0' encoding='UTF-8'?> 
 
<S2SCTScf:SCTScfBlkCredTrf xmlns="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:S2SCTScf="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd"> 
 
    <S2SCTScf:SndgInst>XXXXXXXX</S2SCTScf:SndgInst> 
 
    <S2SCTScf:RcvgInst>YYYYYYYY</S2SCTScf:RcvgInst> 
 
    <S2SCTScf:SrvcId>SCT</S2SCTScf:SrvcId> 
 
    <S2SCTScf:TstCode>P</S2SCTScf:TstCode> 
 
    <S2SCTScf:FType>SCF</S2SCTScf:FType> 
 
    <S2SCTScf:FileRef>AAAAAAAAAAAAAAAAAAA</S2SCTScf:FileRef> 
 
    <S2SCTScf:RoutingInd>IND</S2SCTScf:RoutingInd> 
 
    <S2SCTScf:FileBusDt>2016-11-01</S2SCTScf:FileBusDt> 
 
    <S2SCTScf:FileCycleNo>01</S2SCTScf:FileCycleNo> 
 
    <S2SCTScf:FIToFICstmrCdtTrf xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02"> 
 
    <GrpHdr> 
 
     <MsgId>111111111111111111</MsgId> 
 
     <CreDtTm>2016-11-01T15:45:11.0Z</CreDtTm> 
 
     <NbOfTxs>11</NbOfTxs> 
 
     <TtlIntrBkSttlmAmt Ccy="EUR">111111</TtlIntrBkSttlmAmt> 
 
     <IntrBkSttlmDt>2016-11-01</IntrBkSttlmDt> 
 
     <SttlmInf> 
 
     <SttlmMtd>CLRG</SttlmMtd> 
 
     <ClrSys> 
 
      <Prtry>ST2</Prtry> 
 
     </ClrSys> 
 
     </SttlmInf> 
 
     <InstgAgt> 
 
     <FinInstnId> 
 
      <BIC>XXXXXXXX</BIC> 
 
     </FinInstnId> 
 
     </InstgAgt> 
 
     <InstdAgt> 
 
     <FinInstnId> 
 
      <BIC>XXXXXXXX</BIC> 
 
     </FinInstnId> 
 
     </InstdAgt> 
 
    </GrpHdr> 
 
    <CdtTrfTxInf> 
 
     <PmtId> 
 
     <EndToEndId>NOTPROVIDED</EndToEndId> 
 
     <TxId>XXXXXXXXXXXXXXXXXXXXXXXXXX</TxId> 
 
     </PmtId> 
 
     <PmtTpInf> 
 
     <SvcLvl> 
 
      <Cd>SEPA</Cd> 
 
     </SvcLvl> 
 
     </PmtTpInf> 
 
     <IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt> 
 
     <ChrgBr>SLEV</ChrgBr> 
 
     <Dbtr> 
 
     <Nm>MXXXXXX XXXXXXX</Nm> 
 
     <PstlAdr> 
 
      <Ctry>XX</Ctry> 
 
      <AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine> 
 
     </PstlAdr> 
 
     </Dbtr> 
 
     <DbtrAcct> 
 
     <Id> 
 
      <IBAN>XXXXXXXXXXXXXXXXXXXX</IBAN> 
 
     </Id> 
 
     </DbtrAcct> 
 
     <DbtrAgt> 
 
     <FinInstnId> 
 
      <BIC>XXXXXXXXXXX</BIC> 
 
     </FinInstnId> 
 
     </DbtrAgt> 
 
     <CdtrAgt> 
 
     <FinInstnId> 
 
      <BIC>XXXXXXXXXX</BIC> 
 
     </FinInstnId> 
 
     </CdtrAgt> 
 
     <Cdtr> 
 
     <Nm>XXXXXXXXXXXXXXXXXXXXXXX</Nm> 
 
     </Cdtr> 
 
     <CdtrAcct> 
 
     <Id> 
 
      <IBAN>XXXXXXXXXXXXXXXXXXXXXXX</IBAN> 
 
     </Id> 
 
     </CdtrAcct> 
 
     <RmtInf> 
 
     <Ustrd>XXXXXXXXXXXXXXXXXXXXXXX</Ustrd> 
 
     </RmtInf> 
 
    </CdtTrfTxInf> 
 
    <CdtTrfTxInf> 
 
     <PmtId> 
 
     <EndToEndId>NOTPROVIDED</EndToEndId> 
 
     <TxId>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</TxId> 
 
     </PmtId> 
 
     <PmtTpInf> 
 
     <SvcLvl> 
 
      <Cd>SEPA</Cd> 
 
     </SvcLvl> 
 
     </PmtTpInf> 
 
     <IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt> 
 
     <ChrgBr>SLEV</ChrgBr> 
 
     <Dbtr> 
 
     <Nm>XXXXXXXXXXXXXXXXX</Nm> 
 
     <PstlAdr> 
 
      <Ctry>XX</Ctry> 
 
      <AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine> 
 
     </PstlAdr> 
 
     </Dbtr> 
 
     <DbtrAcct> 
 
     <Id> 
 
      <IBAN>XXXXXXXXXXXXXXXXXXXXXXXXX</IBAN> 
 
     </Id> 
 
     </DbtrAcct> 
 
     <DbtrAgt> 
 
     <FinInstnId> 
 
      <BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC> 
 
     </FinInstnId> 
 
     </DbtrAgt> 
 
     <CdtrAgt> 
 
     <FinInstnId> 
 
      <BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC> 
 
     </FinInstnId> 
 
     </CdtrAgt> 
 
     <Cdtr> 
 
     <Nm>XXXXXXXXXXXXXXXXXXXXXXXX</Nm> 
 
     </Cdtr> 
 
     <CdtrAcct> 
 
     <Id> 
 
      <IBAN>XXXXXXXXXXXXXXXXXXXXXXXXXX</IBAN> 
 
     </Id> 
 
     </CdtrAcct> 
 
     <RmtInf> 
 
     <Ustrd>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Ustrd> 
 
     </RmtInf> 
 
    </CdtTrfTxInf> 
 
    </S2SCTScf:FIToFICstmrCdtTrf> 
 
</S2SCTScf:SCTScfBlkCredTrf>

私はOPENXMLを試してみても、XQueryの機能が、私は、名前空間(または名前空間URI)を宣言し、使用上のいくつかの問題を抱えています。私はそのような複雑なXMLと名前空間に精通していない。私はテーブルにデータを鳴らすために理想が必要です。私は1つの名前空間であっても、より単純なxmlを使って成功しました。私はてmanualy最初の11行を削除したと選択怒鳴るは...

DECLARE @XML AS XML, @hDoc AS INT, @SQL NVARCHAR (MAX) 
 
SELECT @XML = XMLData FROM XMLwithOpenXML where id=6 --this is the xml without first 11 lines 
 
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML 
 
SELECT * FROM OPENXML(@hDoc, 'FIToFICstmrCdtTrf/CdtTrfTxInf') 
 
    WITH 
 
    (
 
    CCY [varchar](100) 'IntrBkSttlmAmt/@Ccy', 
 
    IntrBkSttlmAmt [varchar](100) 'IntrBkSttlmAmt', 
 
    TxId [varchar](100) 'PmtId/TxId', 
 
    EndToEndId [varchar](100) 'PmtId/EndToEndId', 
 
    ChrgBr [varchar](100) 'ChrgBr' 
 
    --etc 
 
) 
 
EXEC sp_xml_removedocument @hDoc 
 
GO

答えて

1

  • FROM OPENXMLが古くなって、それ以上使用すべきではありません最初のいくつかの発言を非常にうまく動作します(まれな例外出口)
  • XMLに明示的なエンコーディングが含まれています<?xml version=''1.0'' encoding=''UTF-8''?>。これにより、VARCHAR -pathを実行する必要があります。これは、平易なラテン文字ではない接続で危険です。これをutf-16に置き換え、NVARCHAR -pathに変更するとよいでしょう。この場合、にXMLリテラルの前に "N"を設定する必要があります。
  • 非常に複雑な名前空間に対処する必要があります...読みにくい...名前が繰り返されていないことが確かであれば、名前空間宣言を取り除き、*:を各要素の前に置きます。
  • 追加の作業:S2SCTScf:FIToFICstmrCdtTrfには新しいデフォルト名前空間が定義されています。私はinnerDefltでこれをエイリアスしました。

これは、変数の宣言

DECLARE @xml XML= 
'<?xml version=''1.0'' encoding=''UTF-8''?> 
<S2SCTScf:SCTScfBlkCredTrf xmlns="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:S2SCTScf="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd"> 
    <S2SCTScf:SndgInst>XXXXXXXX</S2SCTScf:SndgInst> 
    <S2SCTScf:RcvgInst>YYYYYYYY</S2SCTScf:RcvgInst> 
    <S2SCTScf:SrvcId>SCT</S2SCTScf:SrvcId> 
    <S2SCTScf:TstCode>P</S2SCTScf:TstCode> 
    <S2SCTScf:FType>SCF</S2SCTScf:FType> 
    <S2SCTScf:FileRef>AAAAAAAAAAAAAAAAAAA</S2SCTScf:FileRef> 
    <S2SCTScf:RoutingInd>IND</S2SCTScf:RoutingInd> 
    <S2SCTScf:FileBusDt>2016-11-01</S2SCTScf:FileBusDt> 
    <S2SCTScf:FileCycleNo>01</S2SCTScf:FileCycleNo> 
    <S2SCTScf:FIToFICstmrCdtTrf xmlns="urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02"> 
    <GrpHdr> 
     <MsgId>111111111111111111</MsgId> 
     <CreDtTm>2016-11-01T15:45:11.0Z</CreDtTm> 
     <NbOfTxs>11</NbOfTxs> 
     <TtlIntrBkSttlmAmt Ccy="EUR">111111</TtlIntrBkSttlmAmt> 
     <IntrBkSttlmDt>2016-11-01</IntrBkSttlmDt> 
     <SttlmInf> 
     <SttlmMtd>CLRG</SttlmMtd> 
     <ClrSys> 
      <Prtry>ST2</Prtry> 
     </ClrSys> 
     </SttlmInf> 
     <InstgAgt> 
     <FinInstnId> 
      <BIC>XXXXXXXX</BIC> 
     </FinInstnId> 
     </InstgAgt> 
     <InstdAgt> 
     <FinInstnId> 
      <BIC>XXXXXXXX</BIC> 
     </FinInstnId> 
     </InstdAgt> 
    </GrpHdr> 
    <CdtTrfTxInf> 
     <PmtId> 
     <EndToEndId>NOTPROVIDED</EndToEndId> 
     <TxId>XXXXXXXXXXXXXXXXXXXXXXXXXX</TxId> 
     </PmtId> 
     <PmtTpInf> 
     <SvcLvl> 
      <Cd>SEPA</Cd> 
     </SvcLvl> 
     </PmtTpInf> 
     <IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt> 
     <ChrgBr>SLEV</ChrgBr> 
     <Dbtr> 
     <Nm>MXXXXXX XXXXXXX</Nm> 
     <PstlAdr> 
      <Ctry>XX</Ctry> 
      <AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine> 
     </PstlAdr> 
     </Dbtr> 
     <DbtrAcct> 
     <Id> 
      <IBAN>XXXXXXXXXXXXXXXXXXXX</IBAN> 
     </Id> 
     </DbtrAcct> 
     <DbtrAgt> 
     <FinInstnId> 
      <BIC>XXXXXXXXXXX</BIC> 
     </FinInstnId> 
     </DbtrAgt> 
     <CdtrAgt> 
     <FinInstnId> 
      <BIC>XXXXXXXXXX</BIC> 
     </FinInstnId> 
     </CdtrAgt> 
     <Cdtr> 
     <Nm>XXXXXXXXXXXXXXXXXXXXXXX</Nm> 
     </Cdtr> 
     <CdtrAcct> 
     <Id> 
      <IBAN>XXXXXXXXXXXXXXXXXXXXXXX</IBAN> 
     </Id> 
     </CdtrAcct> 
     <RmtInf> 
     <Ustrd>XXXXXXXXXXXXXXXXXXXXXXX</Ustrd> 
     </RmtInf> 
    </CdtTrfTxInf> 
    <CdtTrfTxInf> 
     <PmtId> 
     <EndToEndId>NOTPROVIDED</EndToEndId> 
     <TxId>XXXXXXXXXXXXXXXXXXXXXXXXXXXX</TxId> 
     </PmtId> 
     <PmtTpInf> 
     <SvcLvl> 
      <Cd>SEPA</Cd> 
     </SvcLvl> 
     </PmtTpInf> 
     <IntrBkSttlmAmt Ccy="XXX">1.00</IntrBkSttlmAmt> 
     <ChrgBr>SLEV</ChrgBr> 
     <Dbtr> 
     <Nm>XXXXXXXXXXXXXXXXX</Nm> 
     <PstlAdr> 
      <Ctry>XX</Ctry> 
      <AdrLine>XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</AdrLine> 
     </PstlAdr> 
     </Dbtr> 
     <DbtrAcct> 
     <Id> 
      <IBAN>XXXXXXXXXXXXXXXXXXXXXXXXX</IBAN> 
     </Id> 
     </DbtrAcct> 
     <DbtrAgt> 
     <FinInstnId> 
      <BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC> 
     </FinInstnId> 
     </DbtrAgt> 
     <CdtrAgt> 
     <FinInstnId> 
      <BIC>XXXXXXXXXXXXXXXXXXXXXXXX</BIC> 
     </FinInstnId> 
     </CdtrAgt> 
     <Cdtr> 
     <Nm>XXXXXXXXXXXXXXXXXXXXXXXX</Nm> 
     </Cdtr> 
     <CdtrAcct> 
     <Id> 
      <IBAN>XXXXXXXXXXXXXXXXXXXXXXXXXX</IBAN> 
     </Id> 
     </CdtrAcct> 
     <RmtInf> 
     <Ustrd>XXXXXXXXXXXXXXXXXXXXXXXXXXXXX</Ustrd> 
     </RmtInf> 
    </CdtTrfTxInf> 
    </S2SCTScf:FIToFICstmrCdtTrf> 
</S2SCTScf:SCTScfBlkCredTrf>'; 

であり、これはクエリです:すべての名前空間の最初には、宣言されています。あなたのノードは純粋に構造化された1:1なので、要素名の後に要素名を追加するだけで読むことができ、XPathを形成します。 <CdtTrfTxInf>のみが2度表示され、1:n-approachAPPLY.nodes()が必要です。

私の例では、XMLに隠されたあらゆる種類のデータ用に1つのテンプレートが用意されています。後は君しだい。

WITH XMLNAMESPACES(DEFAULT 'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf' 
          ,'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf' as S2SCTScf 
          ,'http://www.w3.org/2001/XMLSchema-instance' AS xsi 
          ,'urn:S2SCTScf:xsd:$SCTScfBlkCredTrf SCTScfBlkCredTrf.xsd' AS schemaLocation 
          ,'urn:iso:std:iso:20022:tech:xsd:pacs.008.001.02' AS innerDeflt) 
SELECT rt.value(N'(S2SCTScf:SndgInst)[1]','nvarchar(max)') AS SndgInst 
     ,rt.value(N'(S2SCTScf:RcvgInst)[1]','nvarchar(max)') AS RcvgInst 
     --more like this 
     ,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:MsgId)[1]','nvarchar(max)') AS MsgId 
     ,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:CreDtTm)[1]','datetime') AS CreDtTm 
     --more like this 
     ,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:TtlIntrBkSttlmAmt/@Ccy)[1]','nvarchar(max)') AS TtlIntrBkSttlmAmt_Ccy 
     ,rt.value(N'(S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:GrpHdr/innerDeflt:TtlIntrBkSttlmAmt)[1]','int') AS TtlIntrBkSttlmAmt 
     --all nodes are 1:1, just "more of the same" 
     --But CdtTrfTxInf is there twice, therefore the call to OUTER APPLY rt.nodes() 
     ,cti.value(N'(innerDeflt:PmtId/innerDeflt:EndToEndId)[1]','nvarchar(max)') AS EndToEndId 
     --all the rest is following the same schema... 
FROM @xml.nodes(N'S2SCTScf:SCTScfBlkCredTrf') AS A(rt) --root 
OUTER APPLY rt.nodes(N'S2SCTScf:FIToFICstmrCdtTrf/innerDeflt:CdtTrfTxInf') AS B(cti) --CdtTrfTxInf 

部分的な結果(キャプションは...シフト)

SndgInst RcvgInst MsgId    CreDtTm  TtlIntrBkSttlmAmt_Ccy TtlIntrBkSttlmAmt EndToEndId 
XXXXXXXX YYYYYYYY 111111111111111111 2016-11-01 15:45:11.000 EUR 111111 NOTPROVIDED 
XXXXXXXX YYYYYYYY 111111111111111111 2016-11-01 15:45:11.000 EUR 111111 NOTPROVIDED 
+0

うわー。これは素晴らしいです。 1000回感謝ありがとう:))。私はTtlIntrBkSttlmAmtをintからdecimalに変更するだけで、魅力的に機能します。私は今、select文ですべてのフィールドを追加し続けます。 –