SQL 在 UPDATE 中使用内联 XML 变量总是得到 null

SQL using inline XML variable in UPDATE always get null

我已尝试使此代码正常工作,但输出 1、输出 2 的结果始终为 NULL

我在 UPDATE 后测试了变量@xml,但是@xml 也是 NULL。这使得 xml 查询在 SET return NULL.

CREATE FUNCTION fnXml
    (
      @input1 DECIMAL(8, 2) ,
      @input2 INT   
    )
RETURNS XML
AS 
    BEGIN
        DECLARE @xml XML
        SET @xml = ( SELECT @input1 + 1 AS c ,
                            @input2 + 2 AS i
                   FOR
                     XML PATH('r')
                   )
        RETURN @xml
    END
GO 


CREATE TABLE TestXml
    (
      ID INT ,
      Input1 DECIMAL(8, 2) ,
      Input2 INT ,
      Output1 DECIMAL(8, 2) ,
      Output2 INT
    )

INSERT  TestXml
VALUES  ( 1, 1, 2, NULL, NULL )
INSERT  TestXml
VALUES  ( 2, 3, 4, NULL, NULL )

DECLARE @xml XML

UPDATE  TestXml
SET     @xml = dbo.fnXml(Input1, Input2) , -- @xml is always NULL ???
        Output1 = ( SELECT  r.value('.', 'decimal(9,2)') AS item
                    FROM    @xml.nodes('//c') AS records ( r )
                  ) ,
        Output2 = ( SELECT  r.value('.', 'decimal(9,2)') AS item
                    FROM    @xml.nodes('//i') AS records ( r )
                  )


SELECT  *
FROM    testxml
/*
Result
ID  Input1  Input2  Output1 Output2
1   1.00    2   NULL    NULL
2   3.00    4   NULL    NULL
*/

--test fnXml independently
SET @xml = dbo.fnXml(1,2)

SELECT  r.value('.', 'decimal(9,2)') AS item
                    FROM    @xml.nodes('//c') AS records ( r )
/*
Result: 
item
2.00
*/

有人遇到过这个问题吗?

请帮忙。

谢谢

更新:我又做了一次测试。如果不是 XML,行内变量工作正常,如下例:

CREATE FUNCTION fnTestNumber ( @input1 INT )
RETURNS INT
AS 
    BEGIN 
        RETURN @input1 + 1
    END
GO 

CREATE TABLE TestNumber
    (
      ID INT ,     
      Input1 INT ,
      Output1 INT,
      Output2 INT
    )

INSERT  TestNumber VALUES  ( 1, 1, NULL, NULL )
INSERT  TestNumber VALUES  ( 2, 2, NULL, NULL )

DECLARE @temp INT

UPDATE  TestNumber
SET     @temp = dbo.fnTestNumber(Input1),
        Output1 = @temp + 1,
        Output2 = @temp + 2


SELECT  * FROM    TestNumber
/* Result
ID  Input1  Output1 Output2
1   1   3   4
2   2   4   5
*/

结果符合预期,XML inline-variable 有什么问题吗?

使用WITH语句:

;WITH t AS 
(
    SELECT  dbo.fnXml(Input1, Input2) AS NewXML,Output1,Output2
    FROM TestXml
 )

UPDATE t
SET Output1=NewXML.value('(/r//c/node())[1]', 'DECIMAL(8,2)'),
Output2=NewXML.value('(/r//i/node())[1]', 'INT') 

SELECT  *
FROM    testxml

不明白你的问题(见我的评论)但我可以提供简单的解决方案:

UPDATE t
SET Output1 = x.value('(/r/c)[1]','decimal(8,2)'),
    Output2 = x.value('(/r/i)[1]','int')
FROM TestXml t
CROSS APPLY (
    SELECT dbo.fnXml(t.Input1, t.Input2) as x
    ) fX

SELECT  *
FROM    testxml

输出:

ID  Input1  Input2  Output1 Output2
1   1.00    2       2.00    4
2   3.00    4       4.00    6

没有XML(相同的输出):

UPDATE testxml
SET Output1 = Input1 + 1, 
    Output2 = Input2 + 2