具有SP_ExecuteSql的完全限定表名以访问远程服务器

时间:2009-11-18 20:03:48

标签: sql sql-server sql-server-2005 linked-server sp-executesql

尝试更新链接服务器上的表(SQL 2000/2005),但我的服务器名称将不会提前知道。我正在尝试这个:

DECLARE @Sql NVARCHAR(4000)
DECLARE @ParamDef NVARCHAR(4000)
DECLARE @SERVER_NAME VARCHAR(35)

SET @Sql = 'UPDATE
@server_name_param.dba_sandbox.dbo.SomeTable
SET SomeCol=''data'''

SET @ParamDef = N'@server_name_param VARCHAR(35)'

print @Sql

exec sp_executesql @Sql, @ParamDef, @server_name_param=@SERVER_NAME

返回此内容:

UPDATE
@server_name_param.dba_sandbox.dbo.SomeTable
SET SomeCol='data'
Msg 170, Level 15, State 1, Line 2
Line 2: Incorrect syntax near '.'.

有什么想法吗?无论如何我在查看参数绑定后正在执行的SQL语句吗?

3 个答案:

答案 0 :(得分:4)

你必须这样做,它不能参数化

....
SET @Sql = 'UPDATE ' + @server_name_param + '.dba_sandbox.dbo.SomeTable SET SomeCol=''data'''
....

编辑:我在纯DBA时代还有另一种方法

EXEC sp_setnetname 'AdhocServer', @SERVER_NAME
UPDATE AdhocServer.dba_sandbox.dbo.SomeTable SET SomeCol 'data'
EXEC sp_setnetname 'AdhocServer', 'MeaninglessValue'
从SQL Server 2000到2008

sp_setnetname

EDIT2。 Permissions

尝试EXECUTE AS LOGIN = 'login_name',其中login_name是超级用户

我没有真正使用过这个(我使用“AS USER”进行测试),所以不确定更精细的点......

编辑3:对于并发性,请考虑使用sp_getapplock和存储过程,或其他一些并发控制机制。

答案 1 :(得分:0)

您无法直接使用参数执行此操作 - 您必须使用动态SQL,或将服务器名称作为参数发送到执行动态SQL的SP:

DECLARE @template NVARCHAR(4000) 
DECLARE @Sql NVARCHAR(4000) 
DECLARE @SERVER_NAME VARCHAR(35) 

SET @template = 'UPDATE {@server_name_param}.dba_sandbox.dbo.SomeTable SET SomeCol=''data''' 
SET @sql = REPLACE(@template, '{@server_name_param}', @SERVER_NAME)

print @Sql 

exec sp_executesql @Sql -- OR EXEC ( @sql )

答案 2 :(得分:0)

我喜欢gbn的伎俩。我不知道那一个,我将不得不再研究一下。

由于我不知道这个技巧,我在过去的类似情况下不得不使用动态sql(就像Cade发布的那样)。当发生这种情况时,我通常会在构建查询之前查询信息架构视图以确保参数值是真正的数据库对象。这样我确定这不是注射尝试。