Como escrevo SQL portátil que se refere a um servidor vinculado?


9

Eu tenho um procedimento armazenado que se refere a um servidor vinculado. Em vários lugares ao longo do procedimento, tenho algo parecido com o seguinte:

INSERT INTO [TableName]
(...Columns...)
SELECT ...Columns...
FROM [ServerName\InstanceName].[Catalogue].[dbo].[TableName]
WHERE TableNameID = @TableNameID

Este procedimento existe no meu ambiente de desenvolvimento, ambiente de teste e ambiente ao vivo.

O problema é que cada cópia do procedimento é sutilmente diferente porque os nomes dos servidores são diferentes para cada ambiente. Isso torna o gerenciamento da implantação de atualizações de script problemático.

Existe uma maneira de tornar o procedimento portátil para que cada ambiente possa executar versões idênticas?

Caso contrário, há algo que eu possa fazer para tornar a implantação de scripts menos propensa a erros / erros?


3
A criação de uma exibição que difere em cada servidor é uma opção? Você poderia definir a vista como SELECT <fields> FROM <linked server>, mas usar o mesmo nome vista em todos os servidores para manter o código mantido
JNK

@JNK não é uma má idéia, existem algumas tabelas, mas pelo menos as visualizações seriam mais fáceis de manter do que um procedimento armazenado com referências de servidor vinculadas.
Doctor Jones

@ jnk, você deve fazer disso uma resposta.
HLGEM 10/10/12

Respostas:


14

O nome do seu servidor vinculado não precisa ser o nome do servidor. Você pode usar um nome genérico.

EXEC master.dbo.sp_addlinkedserver
    @server = N'COMMONNAME',
    @srvproduct=N'MSDASQL',
    @provider=N'SQLNCLI',
    @provstr=N'DRIVER={SQL Server};SERVER=ACTUALSERVERNAME;UID=user1;PWD=rosebud567;', 
    @catalog=N'database1'

Configure o servidor vinculado em cada ambiente com o mesmo nome, mas aponte-o para servidores diferentes.


0

Eu gosto da ideia de usar um nome de servidor vinculado genérico. No entanto, em muitos ambientes, isso pode não ser possível. Nesse caso, você pode usar SQl dinâmico em seu sp.

declare @linkedservername nvarchar(200)
declare @sql nvarchar(4000)
SET @linkedservername =  CASE @@ServerName  
                            WHEN 'DevServer' THEN 'LinkedServerForDevEnvironment'
                            WHEN 'TestServer' THEN 'LinkedServerForTestEnvironment'
                            WHEN 'ProdServer' THEN 'LinkedServerForProdEnvironment'
                            ELSE Null
                        END   

set @sql = 'INSERT INTO [TableName] 
(...Columns...) 
SELECT ...Columns... 
FROM ' + @linkedservername + '.[Catalogue].[dbo].[TableName] 
WHERE TableNameID = @TableNameID'

Exec  @sql

11
Observarei que, se eu estivesse fazendo isso na vida real, usaria um bloco try catch e apresentaria um erro se @linkedservername fosse nulo após a instrução set para avisar que isso foi executado no servidor errado.
HLGEM 10/10/12

11
Se você adotasse essa abordagem, acho que envolveria a instrução CASE em uma função; se um servidor fosse alterado, seria necessário apenas atualizar a função.
Eli

Bom ponto @Eli
HLGEM 10/10
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.