Monday, February 23, 2009

MSSQL USING SYNONYMS FOR REMOTE CONNECTIONS

When using remote server connections in MSSQL they need to be in the format select * from [ServerName].[DatabaseName].[SchemaName].[TableName]. If you want to switch between two servers (say Production and Test) you only need to recreate the LinkedServer. The problem arises when the database and or schema name on the linked server is different. [ProductionData].[Pub] -> [TestData].[dbo]. This change would mean that you have to change every query which reference to the linked server.

A solution is using Synonyms instead. This means that you can use select * from [SynonymSchemaName].[Synonym] instead. The big advantage is that you can script the creating of synonyms, so a database connection switch can be done in seconds rather then hours.

This article contains a csp_ (Ciber Stored Procedure) for this task.

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO

-- =============================================

-- Author: John Minkjan

-- Create date: 20090223

-- Description: Automaticly creates synonyms for

-- table in (remote) database

-- v001 - initial version

-- =============================================

alter PROCEDURE csp_CreateSynonyms (

-- Add the parameters for the stored procedure here

@SeverName varchar(255),

-- holds the remote servername (optional)

@DatabaseName varchar(255),

-- holds the remote databasename ( NOT optional)

@SchemaName varchar(255),

-- holds the remote schemaname (Default: dbo)

@TargetSchemaName varchar(255),

-- holds the target schemaname for the synonyms (default: dbo)

@ReturnMessage varchar(400) output

)

AS

declare @sqlString varchar(4000)

-- holds the native SQL

declare @TableName varchar(255)

-- holds the TableName

BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from

-- interfering with SELECT statements.

SET NOCOUNT ON;

-- Cleanup @Servername

if ( ltrim(rtrim(@SeverName)) is null or

ltrim(rtrim(@SeverName)) = '' )

begin

set @SeverName = ''

end

else

begin

set @SeverName = ltrim(rtrim(@SeverName)) + '.'

end

-- Cleanup DataBase Name

set @DatabaseName = ltrim(rtrim(@DatabaseName)) + '.'

-- Cleanup @SchemaName

if ( ltrim(rtrim(@SchemaName)) is null or

ltrim(rtrim(@SchemaName)) = '' )

begin

set @SchemaName = 'dbo'

end

else

begin

set @SchemaName = ltrim(rtrim(@SchemaName))

end

-- Cleanup @TargetSchemaName

if ( ltrim(rtrim(@TargetSchemaName)) is null or

ltrim(rtrim(@TargetSchemaName)) = '' )

begin

set @TargetSchemaName = 'dbo'

end

else

begin

set @TargetSchemaName = ltrim(rtrim(@TargetSchemaName))

end

-- Set the Cursor

set @sqlString = 'declare SynonymCur cursor for ' +

'SELECT t1.name AS TableName ' +

'FROM (SELECT * '+

'FROM '+ @SeverName + @DatabaseName + 'sys.objects) AS t1 INNER JOIN ' +

'(SELECT * ' +

'FROM '+ @SeverName + @DatabaseName + 'sys.schemaS) AS t2 ON t1.schema_id = t2.schema_id '+

'WHERE (t1.type = ''U'') and t2.name = '+ CHAR(39) + @SchemaName + CHAR(39)

exec (@sqlString)

Open SynonymCur

fetch next from SynonymCur into @TableName

while @@fetch_status=0

begin

-- Create and Execute Drop Statemen

set @sqlString = 'IF EXISTS (SELECT * FROM ' +

'sys.synonyms WHERE name = N'+ CHAR(39)+ @TableName+ ''') ' +

'DROP SYNONYM ['+ @TargetSchemaName + '].[' + @TableName+ '] '

exec (@sqlString)

-- Create and Execute Create Statement

set @sqlString = 'CREATE SYNONYM ['+ @TargetSchemaName + '].[' + @TableName+ '] ' +

'FOR '+ @SeverName + @DatabaseName + '['+ @SchemaName + '].[' + @TableName+ '] '

PRINT @sqlString

exec (@sqlString)

fetch next from SynonymCur into @TableName

end

-- Clean up

close SynonymCur

deallocate SynonymCur

-- Feedback

set @ReturnMessage = 'Succes'

END

GO

Till Next Time

Monday, February 16, 2009

MSSQL add linkend server

http://doc.ddart.net/mssql/sql70/sp_adda_17.htm

USE master
GO
EXEC sp_addlinkedserver
'SEATTLESales',
N'SQL Server'
GO

Till Next Time