Предложения: xQuery, где предикат фильтра дает неожиданные результаты

У меня есть следующий xml, который анализируется через базу данных MSSQL с использованием OPENXML с фильтром xquery для захвата правильных строк. К сожалению, кажется, что он не захватывает соответствующие строки, что заставляет меня чесать голову.

Используя следующий XML, я хочу вставить только один адрес электронной почты, где Method="Insert", и игнорировать оставшиеся два адреса, где метод отсутствует или имеет другое значение (которые были ранее вставлены).

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

Я использую этот оператор sql:

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

Как есть, все три адреса электронной почты будут вставлены, даже если первый и последний узлы электронной почты не имеют атрибута «Метод». Однако, если я добавлю «Метод = «DontAdd»» к двум другим адресам электронной почты, ничего не будет вставлено. .

Я также пытался использовать предикат:

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

Результат аналогичен — он вставляет все строки и, кажется, игнорирует тот факт, что два элемента Email_Address не имеют атрибута Method="Insert", независимо от того, существует ли атрибут Method.

Цель состоит в том, чтобы отфильтровать XML по мере его измельчения и добавить только адрес электронной почты с атрибутом Method="Insert". Прямо сейчас я считаю, что на самом деле у меня есть «Если вы найдете метод =« Вставить »в наборе данных, вставьте все строки» против «если вы найдете метод =« вставить », вставьте только те строки, которые имеют этот атрибут».

Заранее спасибо.


person Greg    schedule 10.02.2017    source источник


Ответы (1)


Обратите внимание на следующий ответ для тех, кто может помочь в будущем. После извлечения столбца «Метод» в запросе с псевдонимом z я смог использовать стандартный 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'
person Greg    schedule 12.02.2017