2017-02-10 7 views
0

xqueryフィルタを使用してOPENXMLを使用してMSSQLデータベースを介して解析されている次のxmlがあります。残念ながら、それは私の頭を傷つける適切な行をつかむようではありません。提案:フィルタ述語が予期しない結果を返すxQuery

次のXMLを使用して、Method = "Insert"のところに単一の電子メールアドレスを挿入し、Methodが存在しないか、または以前に挿入された別の値を持つ残りの2つのアドレスを無視します。私は、このSQL文を使用しています

<Entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" ActiveEntityID="0"> 
    <Entity_Businesses> 
     <Entity_Business EntityTypeID="5" EntityRoleTypeID="9" Method="Update" Name="test business 76" EIN="" EmployeeCount="75" TotalAssets="750000.00"> 
     <Entity_Emails> 
      <Entity_Email ID="85" EmailAddress="[email protected]" /> 
      <Entity_Email ID="0" EmailAddress="[email protected]" Method="Insert"/> 
     </Entity_Emails> 
     <Entity_Contacts> 
      <Entity_Contact ID="162" EntityTypeID="4" EntityRoleTypeID="9" FName="Joe" MName="k" LName="Smith" SSN="444-44-444" JobTitleID="0" DOB="2007-02-27T00:00:00"> 
       <Entity_Emails> 
        <Entity_Email ID="86" EmailAddress="[email protected]"/> 
       </Entity_Emails> 
      </Entity_Contact> 
     </Entity_Contacts> 
     <Entity_Business> 
    </Entity_Businesses> 
</Entities> 

:最初と最後のメールノードは「メソッド」属性を持っていないにもかかわらず

、3つのすべての電子メールアドレスが挿入されているとおり、
INSERT into Entity_Email(bsCol, EmailAddress, xmlID, xmlPID) 
SELECT DENSE_RANK() OVER(ORDER BY y.parentid) AS elementid, z.EmailAddress, y.parentid, z.ID 
FROM OPENXML(@hDoc, '//Entity_Emails', 1) 
WITH (parentid int '@mp:parentid', id int '@mp:id') y 
INNER JOIN OPENXML(@hDoc, N'//Entity_Emails/Entity_Email',1) WITH (EmailAddress nvarchar(100), xmlID int '@mp:id', parentid int '@mp:parentid') as z 
ON y.id = z.parentid 
WHERE @pRI.value('(//Entity_Emails/Entity_Email/@Method)[1]','nvarchar(50)') = 'Insert'; 

、。 。私は、他の2つの電子メールアドレスに、何も挿入されません「メソッド= 『DontAdd』」を追加した場合

しかし、私はまた、述語を使用して試してみました:

WHERE @pRI.exist('//Entity_Emails/Entity_Email[@Method="Insert"]') =1; 
0を

結果は似ています。すべての行が挿入され、Method属性が存在するかどうかにかかわらず、2つのEmail_Address要素に属性がないことを無視しているようです。

目的は、シュレッドされたXMLをフィルタリングし、属性がMethod = "Insert"の電子メールアドレスのみを追加することです。今私が持っていると信じているのは、実際には "メソッド= 'データセットに'挿入 'が見つかった場合は、すべての行を挿入します。

ありがとうございます。

答えて

0

今後の対応については、次の点にご注意ください。エイリアス処理されたクエリで「メソッド」列を取得した後、標準のt-sqlを使用して結果を正しくフィルタリングし、正しい行を挿入できました。

INSERT into Entity_Email(bsCol, EmailAddress, xmlID, xmlPID) 
    SELECT DENSE_RANK() OVER(ORDER BY y.parentid) AS elementid, z.EmailAddress, z.xmlID, y.parentid 
    FROM OPENXML(@hDoc, '//Entity_Emails', 1) 
    WITH (parentid int '@mp:parentid', id int '@mp:id') y 
    INNER JOIN OPENXML(@hDoc, N'//Entity_Emails/Entity_Email',1) WITH (EmailAddress nvarchar(100), xmlID int '@mp:id', parentid int '@mp:parentid', Method nvarchar(50) '@Method') as z 
    ON y.id = z.parentid 
    WHERE z.Method = 'Insert' 
関連する問題