2016-09-11 12 views
2

ヌル取得UPDATEのインラインXML変数を使用してSQLが、OUTPUT1のためのNULL常に結果、私はUPDATE後の変数@xmlをテストしてみたOUTPUT2いつも私はこのコードを動作させるために試してみた

が、@xmlまた、NULLです。このSET xmlクエリは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 
*/ 

誰でもこの問題を経験しましたか?

助けてください。

ありがとうございました

更新:私は別のテストをしました。それは以下のexpampleとして、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のインライン変数の何が問題なのですが予想されますか?

+0

達成したいことはありますか? F.e.あなたのテーブルに 'Output1 DECIMAL(8,2)、Output2 INT'がありますが、このフィールドに'。 '、' decimal(9,2) 'の値を書き込もうとしています。 'Input1'と' Input2'に1と2を追加する必要があるならば、XMLなしで簡単な更新を使うことができます。 – gofr1

+0

関数fnXmlは、UPDATE文でinline-xml-variableを使用するという私の考えを示すものです。私の実際のコードでは、はるかに複雑です:私はデモのコードで見ることができるように、UPDATEで使用する関数から2つの値を2列の値に変更しようとしました。 –

+0

私はFunctionの結果を文字列に連結し、SET節で解析することでこれを達成できますが、XMLインライン変数が機能しない理由を他の専門家に聞きたいと思います。 –

答えて

1

ステートメントで使用する

;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 
+0

解決策1は素晴らしいです。 しかし、ソリューション2は予期しない結果を返します。どちらの行も同じ値のOutput1(4.00)とOutput2(6)を持ちます。 @xmlはステートメント1の最後の割り当ての値を持ち、ステートメント2のすべての更新された行にこの値が使用されているようです。 –

1

いけないあなたが(私のコメントを参照してください)質問を理解するが、私はシンプルなソリューションを提供できます。

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 
+0

CROSS APPLYがうまくいきます! –

関連する問題