2017-02-10 22 views
0

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

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

<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". Сейчас я считаю, что на самом деле «Если вы найдете Method =« Insert »в наборе данных, вставьте все строки« vs. », если вы найдете метод =« insert », вставьте только те строки, которые имеют этот атрибут».

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

ответ

0

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