代码之家  ›  专栏  ›  技术社区  ›  galets

在文本和base64 XML属性之间自动切换的UDF

  •  0
  • galets  · 技术社区  · 15 年前

    我的应用程序将数据序列化为各种XML属性,根据数据的不同,它可能以文本或base64的形式发送数据。在后一种情况下,属性名将为“attribute-base64”。因此,在SQL Server方面,可以使用以下约定来解码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 Server将sql:variable(“@xquery”)理解为XML值,而不是xquery。有什么想法吗?我需要做什么?

    1 回复  |  直到 15 年前
        1
  •  1
  •   Remus Rusanu    15 年前

    不能这样做。XML方法就像SQL查询一样,它们被静态编译到执行计划中,因此不能接受动态部分。如果SQL不能将FROM表接受为变量,则XML不能将xpath和xquery表达式接受为变量。

    您可以使用构造动态SQL,但不能在函数中这样做。