UDF, который автоматически переключается между текстовыми и x64-атрибутами base64 - PullRequest
0 голосов
/ 22 сентября 2009

Мое приложение сериализует данные в различные атрибуты XML и в зависимости от данных может отправлять их в виде текста или в виде base64. В последнем случае имя атрибута будет «attribute-base64». Итак, на стороне сервера SQL можно использовать следующее соглашение для декодирования XML:

declare @DataXml xml
set @DataXml='<root v="test data"/>' ;
--or: set @DataXml='<root v-base64="AgB0AGUAcwB0ACAAHwQSBCQEFw...."/>' ;
SELECT ISNULL( 
    @DataXml.value('root[1]/@v', 'nvarchar(max)'), 
    CAST( @DataXml.value('xs:base64Binary(root[1]/@v-base64)', 
        'varbinary(max)') AS nvarchar(max) ) )

Я пытаюсь написать UDF, который примет XML и имя атрибута в качестве входных данных и выведет строку. Как мне сгенерировать XQuery? Я пытался сделать это, но это не работает:

CREATE FUNCTION dbo. udf_DataXmlValue 
(
    @DataXml xml,
    @NodeName nvarchar(max),
    @AttributeName nvarchar(max)
)
RETURNS nvarchar(max)
AS
BEGIN
    DECLARE @result nvarchar(max) ;

    DECLARE @xquery nvarchar(max) ;
    SET @xquery = @NodeName + '[1]/' + @AttributeName;
    SET @result = @DataXml.value('sql:variable("@xquery")', 'nvarchar(max)') ;

    IF @result IS NULL
    BEGIN
        ... do base64 stuff ...
    END

    RETURN @result ;
END
GO

При вызове:

SELECT dbo.udf_DataXmlValue( @xml, 'root', 'v' )

возвращаемый результат - не значение, а «root [1] / @ v» ... Судя по всему, сервер SQL понимает sql: variable ("@ xquery") как значение XML, а не как XQuery. Любые идеи, что мне нужно сделать?

1 Ответ

1 голос
/ 22 сентября 2009

Вы не можете. Методы XML похожи на запросы SQL, они статически компилируются в планы выполнения и, следовательно, не могут принимать динамические части. Если SQL не может принять таблицу FROM переменной, XML не может принять выражения XPath и XQuery в качестве переменных.

Вы можете прибегнуть к созданию динамического SQL, но вы не можете сделать это в функции.

...