¿Cómo escribo SQL portátil que se refiere a un servidor vinculado?

9

Tengo un procedimiento almacenado que se refiere a un servidor vinculado. En varios lugares a lo largo del procedimiento, tengo algo como lo siguiente:

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

Este procedimiento existe en mi entorno de desarrollo, entorno de prueba y entorno en vivo.

El problema es que cada copia del procedimiento es sutilmente diferente porque los nombres de los servidores son diferentes para cada entorno. Esto hace que la administración de la implementación de actualizaciones de script sea problemática.

¿Hay alguna manera de hacer que el procedimiento sea portátil para que cada entorno pueda ejecutar versiones idénticas?

Si no, ¿hay algo que pueda hacer para que la implementación del script sea menos propensa a errores?

Doctor jones
fuente
3
¿Es una opción crear una vista que difiere en cada servidor? Puede definir la vista como SELECT <fields> FROM <linked server>pero usar el mismo nombre de vista en todos los servidores para mantener el código mantenido
JNK
@JNK eso no es una mala idea, aunque hay bastantes tablas, pero al menos las vistas serían más simples de mantener que un procedimiento almacenado con referencias de servidores vinculados.
Doctor Jones
@jnk, deberías hacer eso una respuesta.
HLGEM

Respuestas:

14

El nombre de su servidor vinculado no tiene que ser el nombre del servidor. Puedes usar un nombre 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 el servidor vinculado en cada entorno con el mismo nombre, pero en realidad apúntelos a servidores diferentes.

Eli
fuente
0

Me gusta la idea de usar un nombre genérico de servidor vinculado. Sin embargo, en muchos entornos esto puede no ser posible. En este caso, puede usar SQl dinámico en su 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
HLGEM
fuente
1
Notaré que si estuviera haciendo esto en la vida real, estaría usando un bloque try try y generaría un error si @linkedservername era nulo después de la declaración establecida para advertirle que esto se ejecutó en el servidor incorrecto.
HLGEM
1
Si adoptara este enfoque, creo que envolvería la declaración CASE en una función, por lo que si un servidor cambiara, solo tendría que actualizar la función.
Eli
Buen punto @Eli
HLGEM