2016-09-11 6 views
2

Ich habe versucht, diesen Code Arbeit zu machen, aber das Ergebnis ist immer NULL für output1, output2SQL mittels Inline-XML-Variable in UPDATE immer null erhalten

ich die Variable @xml nach UPDATE getestet habe, aber @xml ist auch NULL. Dies macht XML-Abfrage in SET NULL zurückgeben.

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 
*/ 

Hat jemand Erfahrung mit diesem Problem?

Bitte helfen.

Dank

UPDATE: Ich habe einen weiteren Test gemacht. Die Inline-Variable funktionieren, wenn es nicht XML, als expample unten war: ist

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 
*/ 

Das Ergebnis wie erwartet, was mit XML-inline-Variable falsch?

+0

Was möchten Sie erreichen? F. e. Sie haben 'Output1 DECIMAL (8, 2), Output2 INT' in Ihrer Tabelle, aber Sie versuchen,'. ',' Dezimal (9,2) 'Werte in diesen Feldern zu schreiben, warum? Wenn Sie 1 und 2 zu "Input1" und "Input2" hinzufügen müssen, können Sie ein einfaches Update ohne XML verwenden. – gofr1

+0

Funktion fnXml ist nur zum Demonstrieren meiner Idee der Verwendung von inline-xml-Variable in UPDATE-Anweisung. In meinem echten Code ist es viel komplexer: Ich habe versucht, 2 Werte von einer Funktion zurückzugeben, um in UPDATE den Wert von 2 Spalte zu ändern, wie Sie in meinem Demo-Code sehen können. –

+0

Ich kann dies durch Verketten Ergebnis in Funktion in Zeichenfolge erreichen und analysieren sie in SET-Klausel, aber ich möchte von anderen professionellen hören, warum die XML-Inline-Variable nicht funktioniert. –

Antwort

1

Verwendung MIT Statement:

;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

Lösung 1 funktioniert gut. Aber Lösung 2 gibt unerwartetes Ergebnis zurück. Beide Zeilen haben den gleichen Wert von Output1 (4.00) und Output2 (6). Es scheint, dass @xml den Wert der letzten Zuweisung in Anweisung 1 hat, und dieser Wert wird für alle aktualisierten Zeilen in Anweisung 2 verwendet. –

1

Dont verstehen Sie (siehe meinen Kommentar) in Frage, aber ich einfache Lösung bieten könnte:

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 

Ausgang: Ohne

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

XML (gleicher Ausgang):

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

CROSS APPLY funktioniert großartig! –