11

Tôi đã có một truy vấn với một tập hợp các tham số cần chạy nhiều lần với các tham số khác nhau, vì vậy tôi đã bọc nó vào một hàm có giá trị bảng.Giải pháp để gọi hàm có giá trị từ xa trong SQL Server thậm chí còn có nhiều vấn đề hơn

Hàm bảng có giá trị cần thiết được gọi từ máy chủ từ xa. Thật không may, cuộc gọi không thành công trên các máy chủ liên kết với các lỗi:

Msg 4122, Level 16, State 1, Line 29 
Remote table-valued function calls are not allowed. 

Microsoft đã thừa nhận rằng "gọi một hàm bảng giá trị từ xa" là một tính năng gạt ra khỏi SQL Server 2008. Xem: http://connect.microsoft.com/SQLServer/feedback/details/276758/remote-table-valued-function-calls-are-not-allowed

Tôi đã phát hiện ra một giải pháp thay thế bằng cách sử dụng cú pháp OPENQUERY, cho phép truy vấn chạy cục bộ trên máy chủ từ xa và sau đó trả về tập kết quả. Xem: http://social.msdn.microsoft.com/Forums/en/transactsql/thread/7a6e4aa1-630b-4ad5-aee5-15139987adbd

Thật không may, giải pháp này cần một giải pháp thay thế, vì nó yêu cầu chuỗi làm đối số, nghĩa là bạn không thể chuyển biến bằng cú pháp OPENQUERY và thậm chí bạn không thể ghép chuỗi bạn muốn bao gồm các biến mà bạn muốn chuyển tới hàm có giá trị bảng từ xa. Giải pháp thay thế cho cách giải quyết này là xây dựng một cách rõ ràng truy vấn OPENQUERY với SQL động, đảm bảo một chuỗi bình thường được truyền cho nó. Xem: http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/0847ad24-0dfe-4ae1-9788-5516c7830f40/

Tuy nhiên, một vấn đề khác là kết quả này. Ngay cả sau khi đảm bảo tất cả các dấu ngoặc kép và dấu ngoặc kép và dấu ngoặc kép được nhúng chính xác để toàn bộ điều có thể được chuyển qua exec sp_executesql vẫn còn một vấn đề:

Khi truy vấn cuối cùng gọi hàm bảng có giá trị, tôi nhận được lỗi:

OLE DB provider "SQLNCLI10" for linked server "MY_REMOTE_SERVER_NAME" returned message "Deferred prepare could not be completed.". 
Msg 7416, Level 16, State 1, Procedure MyTableValuedFunctionName, Line 22 
Access to the remote server is denied because no login-mapping exists. 

Tôi không chắc tại sao tôi nhận được lỗi này, vì ánh xạ tồn tại cho tên người dùng của tôi và nếu tôi chỉ thay thế hàm có giá trị bảng bằng bảng thực, nó sẽ trả về kết quả tốt . Vấn đề xảy ra với câu lệnh OPENQUERY, bất kể nó được thực hiện với sp_executesql hay không, và như tôi đã nói nó chỉ xảy ra khi gọi một hàm có giá trị bảng.

Bất kỳ ý tưởng nào về cách giải quyết vấn đề này?

Trả lời

14

Bạn đã cố gắng thay đổi này - về cơ bản bạn đẩy cuộc gọi đến các chức năng để xảy ra cục bộ trên hộp điều khiển từ xa:

EXEC REMOTE_SERVER_NAME.db_name..sp_executesql N'SELECT * 
    FROM dbo.MyTableValuedFunctionName();'; 
+0

OPENQUERY đã khiến chức năng chạy cục bộ trên máy chủ từ xa và không quan trọng sp_executesql đang chạy trên máy chủ cục bộ, vì sự cố xảy ra cho dù tôi đã thực thi OPENQUERY có hoặc không có sp_executesql. Nó thực sự hoạt động tốt ngay bây giờ; vấn đề là hàm bảng có giá trị được liên kết ngược lại với máy chủ gốc và tôi quên thêm ánh xạ người dùng từ xa trở lại máy chủ được liên kết thay vì chỉ tên người dùng của tôi mà tôi sẽ sử dụng nếu tôi đang chạy truy vấn cục bộ trên máy chủ từ xa chống lại máy chủ cục bộ được liên kết. – Triynko

+0

Trong mọi trường hợp, cú pháp này có vẻ dễ dàng hơn là gây rối với OPENQUERY. Mặc dù có vẻ như bạn nên có một bản sao cục bộ của hàm có giá trị bảng nếu một nửa công việc của nó là liên kết lại với máy chủ gọi ... –

+0

Lý do truy vấn liên kết ngược lại là truy vấn từ xa phải thực hiện một loạt của trái tham gia chống lại một danh sách tên người dùng trên máy chủ chính. Không có cách nào để chuyển danh sách này qua máy chủ từ xa ngoài máy chủ từ xa để truy vấn nó dưới dạng máy chủ được liên kết. Bất kỳ hình thức truy vấn nào khác sẽ phức tạp hoặc không đáng tin cậy liên quan đến các kết nối bên ngoài và các giá trị trường tên người dùng được kết hợp. – Triynko

-1

Trong trường hợp bạn không thể giải quyết nó bằng cách gọi một EXEC (vì bạn là gọi chức năng này từ một chức năng khác hoặc bạn đang cố gắng làm một cái gì đó như INSERT EXEC nhưng bạn không thể lồng nó, vv), đây là một workarround giải quyết vấn đề này cho tôi:

Bạn có thể tạo một hàm trong máy chủ cục bộ của bạn chạy cùng một truy vấn như hàm từ xa (giả sử bạn biết việc triển khai hàm từ xa) vì bạn có thể truy cập các bảng và "stati c-gọi-chức năng "(bởi openquery) không có vấn đề.

Trong ví dụ, nếu các chức năng điều khiển từ xa là một cái gì đó như thế này:

CREATE FUNCTION dbo.[remote_function] (@param1 varchar(200)) 
RETURNS TABLE AS RETURN 
(SELECT col1, col2, col3 FROM [remote_db].[dbo].[remote_table] where col1 = @param1) 
GO 

Bạn có thể tạo một hàm trong máy chủ địa phương của bạn:

CREATE FUNCTION dbo.[local_function] (@param1 varchar(200)) 
RETURNS TABLE AS RETURN 
(SELECT col1, col2, col3 FROM [remote_server].[remote_db].[dbo].[remote_table] where col1 = @param1) 
GO 

Và sau đó chỉ cần truy vấn chức năng mới của bạn như bạn muốn ...

SELECT col1, col2, col3 FROM dbo.local_function(@param1); 
GO 

Nó sẽ hoạt động không có vấn đề gì.