尝试执行包含OpenRowSet
的动态SQL时出现以下错误返回链接服务器“(null)”的OLE DB提供程序“SQLNCLI10” 消息“延期准备无法完成。” Msg 8180,等级 16,国家1,第83行声明无法准备。消息137, 等级15,状态2,行84必须声明标量变量“@ P1”。
这是一个示例proc
IF OBJECT_ID('dbo.usp_SomeProc') IS NULL
EXEC ('CREATE PROCEDURE dbo.usp_SomeProc AS RETURN 0;');
GO
--DROP PROC dbo.usp_SomeProc
ALTER PROCEDURE dbo.usp_SomeProc
--Input Parameters
@Param1 NVARCHAR(50)
,@Param2 INT
,@Param3 NVARCHAR(11)
AS
BEGIN
SET NOCOUNT ON;
SELECT Param1 = @Param1, Param2 = @Param2, Param3 = @Param3
SET NOCOUNT OFF;
RETURN 0;
END;
GO
这里用动态SQL执行proc - 这个工作
DECLARE @P1 NVARCHAR(50)='Some-Nonsense-Text'
, @P2 INT=98765, @P3 NVARCHAR(11)='Meaningless'
, @SQL NVARCHAR(MAX)
SET @SQL = 'EXEC dbo.usp_SomeProc @Param1=@P1
,@Param2=@P2
,@Param3=@P3'
--PRINT @SQL
EXEC sys.sp_executesql @SQL, N'@P1 NVARCHAR(50), @P2 INT, @P3 NVARCHAR(11)', @P1, @P2, @P3 ;
GO
执行不使用动态SQL的OpenRowSet语句
DECLARE @P1 NVARCHAR(50)='Some-Nonsense-Text', @P2 INT=98765, @P3 NVARCHAR(11)='Meaningless'
SELECT *
INTO dbo.SomeProcTest
FROM OPENROWSET ( 'SQLNCLI','Server=<server>\<instance?;Trusted_Connection=yes;'
,'EXEC xStuff.dbo.usp_SomeProc
@Param1=''Some-Nonsense-Text''
,@Param2=98765
,@Param3=''Meaningless'''
)
SELECT * FROM dbo.SomeProcTest
DROP TABLE dbo.SomeProcTest
GO
使用动态SQL和OPENROWSET执行Proc失败并出现上述错误
DECLARE @ServerInstance NVARCHAR(200) = CAST(SERVERPROPERTY('MachineName') AS NVARCHAR(90))
+'\' +CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(90)) ;
DECLARE @OpenRowSet NVARCHAR(MAX) ;
DECLARE @P1 NVARCHAR(50)='Some-Nonsense-Text', @P2 INT=98765, @P3 NVARCHAR(11)='Meaningless', @SQL NVARCHAR(MAX)
SET @SQL = 'EXEC xStuff.dbo.usp_SomeProc
@Param1=@P1
,@Param2=@P2
,@Param3=@P3'
--PRINT @SQL
SET @OpenRowSet =
'
SELECT *
INTO xStuff.dbo.SomeProcTest
FROM OPENROWSET ( ''SQLNCLI''
,''Server='+@ServerInstance +';Trusted_Connection=yes;''
,'''+ @SQL +'''
)' ;
--PRINT @OpenRowSet
EXEC sys.sp_executesql @OpenRowSet, N'@P1 NVARCHAR(50), @P2 INT, @P3 NVARCHAR(11)', @P1, @P2, @P3 ;
SELECT * FROM xStuff.dbo.SomeProcTest
DROP TABLE xStuff.dbo.SomeProcTest
GO
我哪里错了?
答案 0 :(得分:0)
使用此answer中的示例,我能够修改我的查询以使其正常工作
似乎你无法将变量传递给OPENROWSET,你需要像这样修改初始Query以使其工作
--Execute Proc with dynamic SQL and OPENROWSET
DECLARE @ServerInstance NVARCHAR(200) = CAST(SERVERPROPERTY('MachineName') AS NVARCHAR(90))
+'\' +CAST(SERVERPROPERTY('InstanceName') AS NVARCHAR(90)) ;
DECLARE @OpenRowSet NVARCHAR(MAX) ;
DECLARE @P1 NVARCHAR(50)='Some-Nonsense-Text', @P2 INT=98765, @P3 NVARCHAR(11)='Meaningless', @SQL NVARCHAR(MAX)
SET @SQL = 'EXEC xStuff.dbo.usp_SomeProc
@Param1=''''' +@P1+ '''''
,@Param2=' +CAST(@P2 AS NVARCHAR(20))+ '
,@Param3=''''' +@P3+ ''''''
--PRINT @SQL
SET @OpenRowSet =
'
SELECT *
INTO xStuff.dbo.SomeProcTest
FROM OPENROWSET ( ''SQLNCLI''
,''Server='+@ServerInstance +';Trusted_Connection=yes;''
,'''+ @SQL +'''
)' ;
--PRINT @OpenRowSet
EXEC sys.sp_executesql @OpenRowSet ;--
SELECT * FROM xStuff.dbo.SomeProcTest
DROP TABLE xStuff.dbo.SomeProcTest
GO