【问题标题】:Fully qualified table names with SP_ExecuteSql to access remote server使用 SP_ExecuteSql 访问远程服务器的完全限定表名
【发布时间】:2009-11-18 20:03:48
【问题描述】:

尝试更新链接服务器 (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语句吗?

【问题讨论】:

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


    【解决方案1】:

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

    ....
    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'
    

    sp_setnetname 从 SQL Server 2000 到 2008 都存在

    编辑2。 Permissions:

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

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

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

    【讨论】:

    • 您的编辑实际上比问题更能回答问题。这样做可以让我在不使用任何参数化或动态 sql 的情况下执行我的查询。太棒了!
    • 哦,但不幸的是,根据 msdn,这需要 sysadmin 和 setupadmin 固定服务器角色的成员身份。 - 我们并不真正想应用到应用程序用户的角色。
    【解决方案2】:

    您不能直接使用参数执行此操作 - 您必须使用动态 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 )
    

    【讨论】:

      【解决方案3】:

      我喜欢 gbn 的把戏。我不知道那个,我得再研究一下。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-10-03
        • 2011-11-14
        • 1970-01-01
        • 2012-03-15
        • 2017-04-21
        • 2017-06-16
        • 1970-01-01
        相关资源
        最近更新 更多