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
我已尝试使此代码正常工作,但输出 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