Ich versuche, eine TVF zweimal mit verschiedenen Parametern in der gleichen Abfrage aufzurufen, aber aus irgendeinem Grund, wenn ich die Ergebnisse zusammen, eines der Ergebnisse Art maskiert den anderen. Ich habe mein Problem auf dieses kleine Beispiel reduziert:Aufruf von mehreren Anweisungen TVF mit verschiedenen Parametern in separaten CTEs mit falschen Ergebnissen
Nehmen Sie den Inline-TVF:
CREATE FUNCTION dbo.fnTestErrorInline(@Test INT)
RETURNS TABLE
AS
RETURN
(
SELECT ID, Val
FROM (VALUES
(1, 1, 10),
(1, 2, 20),
(1, 3, 30),
(1, 4, 40),
(2, 1, 50),
(2, 2, 60),
(2, 3, 70),
(2, 4, 80)
) t(Test, ID, Val)
WHERE [email protected]
)
und eine äquivalente mehrzeiligen Funktion:
CREATE FUNCTION dbo.fnTestErrorMultiline(@Test INT)
RETURNS @tbl TABLE (
ID INT NOT NULL,
Val INT NOT NULL
)
AS
BEGIN
IF @Test=1
INSERT INTO @tbl (ID, Val) VALUES
(1, 10),
(2, 20),
(3, 30),
(4, 40);
IF @Test=2
INSERT INTO @tbl (ID, Val) VALUES
(1, 50),
(2, 60),
(3, 70),
(4, 80);
RETURN
END
Wenn ich diese Abfrage ausführen:
WITH cte1 AS (
SELECT ID, SUM(Val) AS Total
FROM dbo.fnTestErrorInline(1)
GROUP BY ID
), cte2 AS (
SELECT ID, SUM(Val) AS Total
FROM dbo.fnTestErrorInline(2)
GROUP BY ID
)
SELECT *
FROM cte1 c1
INNER JOIN cte2 c2 ON c1.ID=c2.ID;
Die Ergebnisse sind wie erwartet:
ID Total ID Total
1 10 1 50
2 20 2 60
3 30 3 70
4 40 4 80
aber wenn ich die mehrzeilige Version der Funktion:
WITH cte1 AS (
SELECT ID, SUM(Val) AS Total
FROM dbo.fnTestErrorMultiline(1)
GROUP BY ID
), cte2 AS (
SELECT ID, SUM(Val) AS Total
FROM dbo.fnTestErrorMultiline(2)
GROUP BY ID
)
SELECT *
FROM cte1 c1
INNER JOIN cte2 c2 ON c1.ID=c2.ID;
die Ergebnisse sind falsch - CTE2 die gleichen Werte wie CTE1 zeigt:
ID Total ID Total
1 10 1 10
2 20 2 20
3 30 3 30
4 40 4 40
Zusätzlich sehe ich nur dieses Verhalten wenn die GROUP BY
vorhanden ist. Ohne es sind die Ergebnisse in Ordnung.
Seltsam, wenn ich eine andere Säule mit dem zweiten CTE hinzufügen, ändert sich die Ergebnisse:
WITH cte1 AS (
SELECT ID, SUM(Val) AS Total
FROM dbo.fnTestErrorMultiline(1)
GROUP BY ID
), cte2 AS (
SELECT ID, SUM(Val) AS Total, SUM(Val+0) AS why
FROM dbo.fnTestErrorMultiline(2)
GROUP BY ID
)
SELECT *
FROM cte1 c1
INNER JOIN cte2 c2 ON c1.ID=c2.ID;
ergibt
ID Total ID Total why
1 50 1 50 50
2 60 2 60 60
3 70 3 70 70
4 80 4 80 80
Es erscheint die zusätzliche Spalte eine Spalte in der TVF Tabelle verweisen muss - ein konstanter Wert dort ändert die Ergebnisse nicht.
Was geht hier vor? Soll ein Multiline-TVF nicht mehr als einmal pro Abfrage aufgerufen werden?
Ich habe das 2008 R2 auf SQL Server getestet und 2012
Bin vorbei 3 bis 'fnTestErrorMultiline' in der zweiten CTE noch kann ich Ergebnisse sehen. http://sqlfiddle.com/#!6/e0395/13. Es ist komisch –
@ MM93 das ist komisch! Das scheint zu implizieren, dass die Funktion nur einmal ausgeführt wird, da das zweite CTE keine Zeilen zum Verknüpfen hätte. Wenn ich den Abfrageplan anschaue, wird "Table Valued Function" zweimal angezeigt, so dass ich wirklich nicht weiß, was passiert. – David
Wenn ich die Reihenfolge (zB) durch '3' nach' fnTestErrorMultiline' im ersten CTE ändere, kann ich keine Ergebnisse sehen –