运行 动态 SQL 带链接服务器的服务器存储过程
Run dynamic SQL Server stored procedure with linked server
这是一个动态存储过程,将传递数据库、链接服务器和状态。执行此存储过程时,它会在链接服务器上的数据库上运行存储过程并返回结果。
工作代码 - 这里的链接服务器是绝对的,没有作为变量传递
EXECUTE MYPROC 'CA','MYDB'
CREATE PROCEDURE [dbo].[MYPROC]
(
@state varchar(2),
@DATABASE char(20)
)
AS
DECLARE @SQL @VARCHAR(MAX)
SELECT @SQL = 'use ' + @DATABASE + ';
SELECT * FROM pubs.dbo.authors WHERE state = @state'
EXEC MYLINKSERVER.master.dbo.sp_executesql
@SQL, N'@state char(2)', @state
无效代码:此处链接服务器通过变量传递。
我在 @LINKEDSERVER**.**master
收到“语法错误”
EXECUTE MYPROC 'CA','MYDB','MYLINKSERVER'
CREATE PROCEDURE [dbo].[MYPROC]
(
@state varchar(2),
@DATABASE char(20),
@LINKEDSERVER VARCHAR(20)
)
AS
DECLARE @SQL @VARCHAR(MAX)
SELECT @SQL = 'use ' + @DATABASE + ';
SELECT * FROM pubs.dbo.authors WHERE state = @state'
EXEC @LINKEDSERVER.master.dbo.sp_executesql
@SQL, N'@state char(2)', @state
提前致谢
在你的 SP 中试试这个:
DECLARE @SQL VARCHAR(MAX);
SET @SQL = FORMATMESSAGE ( 'SELECT * FROM [%s].[%s].[dbo].[authors] WHERE [state] = ''%s'';', @LINKEDSERVER, @DATABASE, @state );
EXEC ( @SQL );
这将创建以下 SQL 语句,根据您上面的示例参数执行:
SELECT * FROM [MYLINKSERVER].[MYDB].[dbo].[authors] WHERE [state] = 'CA';
我不确定您 SQL 服务器的版本 运行,因此您可能无法使用 FORMATMESSAGE
,但是,我确定您'重新熟悉连接字符串。
与使用四部分查询相比,我更喜欢使用 OPENQUERY
as it is usually much faster。所以不用 SELECT * FROM [MYLINKSERVER].[MYDB].[dbo].[authors] WHERE [state] = 'CA';
,试试这个:
SELECT * FROM OPENQUERY([MYLINKSERVER], '
SELECT * FROM [MYDB].[dbo].[authors] WHERE [state] = ''CA''
')
你的程序将是这样的
CREATE PROCEDURE [dbo].[MYPROC]
(
@state CHAR(2),
@DATABASE VARCHAR(20),
@LINKEDSERVER VARCHAR(20)
)
AS
DECLARE @SQL NVARCHAR(500)
SET @SQL = N'SELECT * FROM OPENQUERY(' + QUOTENAME(@LINKEDSERVER) + ', ''
SELECT * FROM ' + QUOTENAME(@DATABASE) + '.dbo.authors WHERE state = ''''' + @state + '''''
'')'
EXEC SP_EXECUTESQL @SQL
--PRINT @SQL -- To see the final query to execute
或者您可以使用 FORMATMESSAGE
作为 Critical Error 给出的答案。
SET @SQL = FORMATMESSAGE ('SELECT * FROM OPENQUERY([%s], ''
SELECT * FROM [%s].[dbo].[authors] WHERE [state] = ''''%s'''''');', QUOTENAME(@LINKEDSERVER), QUOTENAME(@DATABASE), @state
);
EXEC (@SQL);
使用避免SQL注入。由于另一个参数限制为char(2)
,我想它应该是安全的。
这是一个动态存储过程,将传递数据库、链接服务器和状态。执行此存储过程时,它会在链接服务器上的数据库上运行存储过程并返回结果。
工作代码 - 这里的链接服务器是绝对的,没有作为变量传递
EXECUTE MYPROC 'CA','MYDB'
CREATE PROCEDURE [dbo].[MYPROC]
(
@state varchar(2),
@DATABASE char(20)
)
AS
DECLARE @SQL @VARCHAR(MAX)
SELECT @SQL = 'use ' + @DATABASE + ';
SELECT * FROM pubs.dbo.authors WHERE state = @state'
EXEC MYLINKSERVER.master.dbo.sp_executesql
@SQL, N'@state char(2)', @state
无效代码:此处链接服务器通过变量传递。
我在 @LINKEDSERVER**.**master
EXECUTE MYPROC 'CA','MYDB','MYLINKSERVER'
CREATE PROCEDURE [dbo].[MYPROC]
(
@state varchar(2),
@DATABASE char(20),
@LINKEDSERVER VARCHAR(20)
)
AS
DECLARE @SQL @VARCHAR(MAX)
SELECT @SQL = 'use ' + @DATABASE + ';
SELECT * FROM pubs.dbo.authors WHERE state = @state'
EXEC @LINKEDSERVER.master.dbo.sp_executesql
@SQL, N'@state char(2)', @state
提前致谢
在你的 SP 中试试这个:
DECLARE @SQL VARCHAR(MAX);
SET @SQL = FORMATMESSAGE ( 'SELECT * FROM [%s].[%s].[dbo].[authors] WHERE [state] = ''%s'';', @LINKEDSERVER, @DATABASE, @state );
EXEC ( @SQL );
这将创建以下 SQL 语句,根据您上面的示例参数执行:
SELECT * FROM [MYLINKSERVER].[MYDB].[dbo].[authors] WHERE [state] = 'CA';
我不确定您 SQL 服务器的版本 运行,因此您可能无法使用 FORMATMESSAGE
,但是,我确定您'重新熟悉连接字符串。
与使用四部分查询相比,我更喜欢使用 OPENQUERY
as it is usually much faster。所以不用 SELECT * FROM [MYLINKSERVER].[MYDB].[dbo].[authors] WHERE [state] = 'CA';
,试试这个:
SELECT * FROM OPENQUERY([MYLINKSERVER], '
SELECT * FROM [MYDB].[dbo].[authors] WHERE [state] = ''CA''
')
你的程序将是这样的
CREATE PROCEDURE [dbo].[MYPROC]
(
@state CHAR(2),
@DATABASE VARCHAR(20),
@LINKEDSERVER VARCHAR(20)
)
AS
DECLARE @SQL NVARCHAR(500)
SET @SQL = N'SELECT * FROM OPENQUERY(' + QUOTENAME(@LINKEDSERVER) + ', ''
SELECT * FROM ' + QUOTENAME(@DATABASE) + '.dbo.authors WHERE state = ''''' + @state + '''''
'')'
EXEC SP_EXECUTESQL @SQL
--PRINT @SQL -- To see the final query to execute
或者您可以使用 FORMATMESSAGE
作为 Critical Error 给出的答案。
SET @SQL = FORMATMESSAGE ('SELECT * FROM OPENQUERY([%s], ''
SELECT * FROM [%s].[dbo].[authors] WHERE [state] = ''''%s'''''');', QUOTENAME(@LINKEDSERVER), QUOTENAME(@DATABASE), @state
);
EXEC (@SQL);
使用char(2)
,我想它应该是安全的。