【问题标题】:Raise exception if XML element does not exist如果 XML 元素不存在,则引发异常
【发布时间】:2013-12-10 12:14:02
【问题描述】:

我有多个接受 XML 参数的过程(我知道我可以改用 TVP,但它适合应用程序也传递 XML 的旧方法)。

以下代码从 XML 填充表:

DECLARE @tmp TABLE (userID int, colA int);
DECLARE @xml XML = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rows>
    <row userId="1" colA="234" />
    <row userId="1" colB="564" />
    <row userId="1" colA="252" />
</rows>';

INSERT INTO @tmp 
    (userID, colA) 
SELECT 
    u.n.value('@userId', 'int'),
    u.n.value('@colA', 'int')
FROM
    @xml.nodes('/rows/row') AS u (n);

SELECT * FROM @tmp;

但是请注意,XML 的第二行实际上并没有 colA 元素。我知道这会在表中创建一个 NULL,但在我的应用程序中,允许使用 NULL 值。

userID      colA
----------- -----------
1           234
1           NULL
1           252

那么,在填充数据之前,有什么方法可以在 TSQL 中执行某种类型的检查(像这样)?

For each XML row
    If (userId element does not exist) OR (colA element does not exist) Then
        RAISERROR (caught by BEGIN/END TRAN within procedures/calling procedure)

【问题讨论】:

    标签: sql sql-server tsql sql-server-2012 sqlxml


    【解决方案1】:

    您可以为此使用 SQLXML exist

    select @xml.exist('rows/row[not(@colA)]')
    

    如果有一行没有colA 属性,将返回1。所以你可以使用类似

    if @xml.exist('rows/row[not(@colA)]') = 1
        ...
        -- raiserror here
        ...
    

    sql fiddle demo

    【讨论】:

    • 太棒了,谢谢。如果上面的代码在另一个过程调用的过程中,我需要在你的示例之后直接 ROLLBACK,然后在 ROLLBACK 之后直接调用 RAISERROR,还是 ROLLBACK 完全由第一个过程处理?
    【解决方案2】:
    IF EXISTS (SELECT * FROM @tmp WHERE userId IS NULL OR colA IS NULL)
    BEGIN 
      RAISERROR ('Your Error Message', 16, 1)
    
    END 
    

    【讨论】:

    • 抱歉,这不起作用(请参阅我声明允许使用 NULL 的帖子)。还是谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-05
    • 2016-11-07
    • 2011-09-05
    • 2013-07-29
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    相关资源
    最近更新 更多