验证SQL Server 2008R2中的各个XML元素

时间:2011-11-29 21:34:50

标签: sql-server xml sql-server-2008 tsql

我正在编写一个存储过程来处理用户上传的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 个答案:

答案 0 :(得分:1)

纯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变量。在select之后,尝试从try-catch块中分配一个类型化的xml变量。

  4. 结果代码如下:

    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="..."/>:好的   <Person Id="2" FirstName="..." LastName="..."/>:好的   <Person Id="f" FirstName="..." LastName="..."/>:失败了   <Person Id="4" FirstName="..." LastName="..."/>:好的   <Person Id="5" FirstName="..." LastName="..."/>:好的


    更简单的选择是创建一个CLR存储过程,该过程将用.NET语言解析XML。