web-dev-qa-db-ja.com

ストアドプロシージャに動的SQLが含まれているため、メタデータを特定できませんでした

動的SQLを含むストアドプロシージャがあります。 OPENROWSETを使用してストアドプロシージャを実行しようとしていますが、エラーが発生します。

メッセージ11514、レベル16、状態1、プロシージャsp_describe_first_result_set、行1

ステートメント 'EXEC sp_executesql @SQL、N' @ row_count_out INT OUTPUT '、@row_count_out = @row_count_table OUTPUT;'のため、メタデータを特定できませんでした。プロシージャ 'nachoTest'には動的SQLが含まれています。 WITH RESULT SETS句を使用して結果セットを明示的に記述することを検討してください。

私の実際のストアドプロシージャはもう少し複雑ですが、これはエラーの実際の例です。

ストアドプロシージャ:

CREATE PROCEDURE nachoTest  @table_name NVARCHAR(MAX)
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @row_count_table INT
    DECLARE @SQL NVARCHAR(MAX)

    SET @SQL = N'SELECT @row_count_out = COUNT(*) FROM ' + @table_name
    EXEC sp_executesql @SQL, N'@row_count_out INT OUTPUT', @row_count_out = @row_count_table OUTPUT;

    SELECT @row_count_table AS row_count, @table_name AS table_name
END
GO

OPENROWSETで呼び出す

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;', 'EXEC dbo.nachoTest ''e_MFA_All_Tokens''')

オンラインで少し読みましたが、WITH RESULT SETSを使用してコードを修正する方法を理解できません。理想的には、ストアドプロシージャを修正したいのですが、OPENROWSET呼び出しを変更する必要がある場合も問題ありません。

1
IMTheNachoMan

問題はprocではなく、OPENROWSET/OPENQUERYにあります。 SQL Server 2012より前は、結果セットのメタデータを把握するためにset fmtonlyが使用されていました。 2012以降、このエラーの原因となるsp_describe_first_result_setに置き換えられました。

ここでは、結果セットをどのように説明できるかを説明します。

SELECT * FROM OPENROWSET('SQLNCLI', 'Server=localhost;Trusted_Connection=yes;', 'EXEC dbo.nachoTest ''e_MFA_All_Tokens'' WITH RESULT SETS
(
  (
    cnt int, name sysname
  )
)')

EXECUTE WITH RESULT SETSの詳細はこちら: SQL Server 2012 T-SQLの概要– EXECUTE WITH RESULT SETS

5
sepupic