Проверка отдельных элементов XML в SQL Server 2008R2 - PullRequest
0 голосов
/ 30 ноября 2011

Я пишу хранимую процедуру для обработки данных XML, загруженных пользователем:

<People>
    <Person Id="1" FirstName="..." LastName="..." />
    <Person Id="2" FirstName="..." LastName="..." />
    <Person Id="3" FirstName="..." LastName="..." />
    <Person Id="4" FirstName="..." LastName="..." />
    <Person Id="5" FirstName="..." LastName="..." />
</People>

Я хотел бы использовать схему, чтобы убедиться, что сущности действительны, но я не хочувесь процесс потерпит неудачу только из-за одного недопустимого объекта.Вместо этого я хотел бы записать все недействительные сущности в таблицу и обработать действительные сущности как обычно.

Есть ли рекомендуемый способ сделать это?

1 Ответ

1 голос
/ 30 ноября 2011

Подход на чистом SQL будет выглядеть следующим образом:

  1. Создать коллекцию схем, которая определяет <Person>:

    CREATE XML SCHEMA COLLECTION [dbo].[testtest] AS
    N'<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="Person">
          <xs:complexType>
            <xs:attribute name="Id" type="xs:int" use="required"/>
            <xs:attribute name="FirstName" type="xs:string" use="required"/>
            <xs:attribute name="LastName" type="xs:string" use="required"/>
          </xs:complexType>
        </xs:element>
      </xs:schema>
     '
    

    (одноразовая операция)

  2. Имеет запрос XML, который выбирает каждый узел <Person> из <People> в виде отдельной строки.

  3. Объявите курсор на этом запросе и выберите каждыйстрока в нетипизированной переменной XML.После выбора попытайтесь присвоить типизированной переменной xml из блока try-catch.

Результирующий код будет выглядеть следующим образом:

declare @source xml = N'
    <People>
        <Person Id="1" FirstName="..." LastName="..." />
        <Person Id="2" FirstName="..." LastName="..." />
        <Person Id="f" FirstName="..." LastName="..." />
        <Person Id="4" FirstName="..." LastName="..." />
        <Person Id="5" FirstName="..." LastName="..." />
    </People>';

declare foo cursor
local
forward_only
read_only
for
  select t.p.query('.')
  from @source.nodes('People/Person') as t(p)
;

declare @x xml (dbo.testtest);
declare @x_raw xml;

open foo;

fetch next from foo into @x_raw;

while @@fetch_status = 0
begin
  begin try
    set @x = @x_raw;
    print cast(@x_raw as nvarchar(max)) + ': OK';
  end try
  begin catch
    print cast(@x_raw as nvarchar(max)) + ': FAILED';
  end catch;

  fetch next from foo into @x_raw;
end;

close foo;
deallocate foo;

Результат:

<Person Id="1" FirstName="..." LastName="..."/>: OK
<Person Id="2" FirstName="..." LastName="..."/>: OK
<Person Id="f" FirstName="..." LastName="..."/>: FAILED
<Person Id="4" FirstName="..." LastName="..."/>: OK
<Person Id="5" FirstName="..." LastName="..."/>: OK


Более простой вариант - создать хранимую процедуру CLR, которая будет анализировать XML на языке .NET.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...