2013-12-10 3 views
1

У меня есть несколько процедур, которые принимают параметры XML (я знаю, что я мог бы использовать TVP вместо этого, но он соответствует более старому подходу, где приложение также передает XML).Выяснить исключение, если элемент 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) 

ответ

1

Вы можете использовать SQLXML exist для этого:

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

вернется 1, если есть строка, которая не имеет colA атрибут. Таким образом, вы можете использовать что-то вроде

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

sql fiddle demo

+0

Superb, спасибо. Если вышеуказанный код был внутри процедуры, вызванной другой процедурой, мне нужно было бы ROLLBACK сразу после вашего примера, а затем вызвать RAISERROR сразу после ROLLBACK или полностью обработать ROLLBACK первой процедурой? – EvilDr

0
IF EXISTS (SELECT * FROM @tmp WHERE userId IS NULL OR colA IS NULL) 
BEGIN 
    RAISERROR ('Your Error Message', 16, 1) 

END 
+0

Жаль, что это не сработает (см. Сообщение, где я указываю, что разрешены NULL). Спасибо, в любом случае – EvilDr