Вопрос

I have multiple procedures that accept XML parameters (I know I could use a TVP instead, but it fits with an older approach where the application also passes XML).

The following code populates a table from 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;

Note however that the second line of XML doesn't actually have a colA element. I know this creates a NULL in the table, but in my app, NULL values are permitted.

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

So, is there any way to perform some type of check in TSQL (like this) before the data is populated?

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)
Это было полезно?

Решение

You can use SQLXML exist for that:

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

will return 1 if there's a row which doesn't have colA attribute. So you can use something like

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

sql fiddle demo

Другие советы

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

END 
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top