Pergunta

Tentando atualizar uma tabela em um servidor vinculado (SQL 2000/2005), mas o nome do meu servidor não será conhecido antes do tempo. Estou tentando o seguinte:

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

Que retorna o seguinte:

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

Alguma ideia? Existe alguma maneira de ver a instrução SQL que está sendo executada depois que os parâmetros estiverem vinculados?

Foi útil?

Solução

Você terá que fazer isso, não pode ser parametrizado

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

EDIT: Há outra maneira que eu usei nos meus dias de DBA puro

EXEC sp_setnetname 'AdhocServer', @SERVER_NAME
UPDATE AdhocServer.dba_sandbox.dbo.SomeTable SET SomeCol 'data'
EXEC sp_setnetname 'AdhocServer', 'MeaninglessValue'

sp_setnetname está lá do SQL Server 2000 a 2008

Edit2. Permissões:

Tentar EXECUTE AS LOGIN = 'login_name' , onde Login_name é um superusor

Eu realmente não usei isso (eu uso "como usuário" para testes), então não tenho certeza dos pontos mais finos ...

EDIT 3: Para simultaneidade, considere o uso do SP_GETAPPLOCK e um procedimento armazenado, ou algum outro mecanismo de controle de simultaneidade.

Outras dicas

Você não pode fazer isso diretamente com os parâmetros - você precisaria usar o SQL dinâmico ou enviar o nome do servidor como um parâmetro para um SP que faz SQL dinâmico:

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 )

Eu gosto do truque de GBN. Eu não sabia disso e vou ter que pesquisar isso um pouco mais.

Como eu não conhecia esse truque, tive que usar o SQL dinâmico em situações semelhantes no passado (como o que Cade postou). Quando isso acontece, eu normalmente consultaria uma exibição de esquema de informações para garantir que o valor do parâmetro seja um objeto real de banco de dados antes de criar a consulta. Dessa forma, tenho certeza de que não é uma tentativa de injeção.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top