Tôi đang cố gọi TVF hai lần với các tham số khác nhau trong cùng một truy vấn, nhưng vì một số lý do, khi tôi tham gia kết quả cùng nhau, một trong các kết quả loại mặt nạ khác. Tôi đã giảm vấn đề của tôi xuống ví dụ nhỏ này:Gọi TVF đa tuyên bố với các thông số khác nhau trong CTE riêng biệt cho kết quả sai
Đi này TVF inline:
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]
)
và một chức năng multiline tương đương:
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
Nếu tôi chạy truy vấn này:
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;
kết quả như mong đợi:
ID Total ID Total
1 10 1 50
2 20 2 60
3 30 3 70
4 40 4 80
nhưng khi tôi sử dụng phiên bản multiline của hàm:
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;
kết quả là không chính xác - cte2 cho thấy các giá trị tương tự như cte1:
ID Total ID Total
1 10 1 10
2 20 2 20
3 30 3 30
4 40 4 40
Ngoài ra, tôi chỉ nhìn thấy hành vi này khi có GROUP BY
. Không có nó, kết quả là tốt.
Kỳ lạ thay, nếu tôi thêm một cột vào CTE thứ hai, nó làm thay đổi kết quả:
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;
mang
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
Nó xuất hiện cột phụ cần tham khảo một cột trong bảng TVF - một giá trị không đổi không thay đổi kết quả.
Điều gì đang xảy ra ở đây? Bạn không phải gọi một TVF nhiều dòng hơn một lần cho mỗi truy vấn?
Tôi đã thử nghiệm này trên SQL Server 2008 R2 và 2012
Đang chuyển từ 3 đến 'fnTestErrorMultiline' trong CTE thứ hai, tôi vẫn có thể xem kết quả. http://sqlfiddle.com/#!6/e0395/13. –
@ MM93 lạ kỳ lạ của nó! Điều đó dường như ngụ ý hàm chỉ chạy một lần vì CTE thứ hai sẽ không có bất kỳ hàng nào để tham gia. Nhìn vào kế hoạch truy vấn, nó hiển thị 'Bảng Giá trị Chức năng' hai lần, vì vậy tôi thực sự không biết điều gì đang xảy ra – David
Nếu tôi thay đổi thứ tự (tức là) chuyển '3' sang' fnTestErrorMultiline' trong CTE đầu tiên, tôi không thể thấy kết quả –