37

We have a very old software has been created around 10 years ago and we don't have source code.

The software uses two databases, DB01 and DB02 on the same SQL Server 2012 instance.

There is SQL statements such as db01..table1 join db02..table2, but the main issue is our processes don't allow us use db02 as a name of database.

The question is: how we can create an alias of for database?

I was trying to use CREATE SYNONYM

CREATE SYNONYM [db02] FOR [db02_new_name];

but it doesn't work for database names.

Please suggest how it can be solved without patching a binary files to correct SQL statements.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Dmitriy Sosunov
  • 1,075
  • 3
  • 10
  • 25
  • 6
    I don't believe you can. Both of the current answers seem to be missing the point and allowing an alias for server instance, and `SYNONYM`s only work for objects *within* a database. I'm not aware of any way to alias a database name. – Damien_The_Unbeliever Feb 12 '14 at 08:47

7 Answers7

14

Create a database with the name you want to impersonate. Re-jigg the DDL code generator to create a view for every table in the database that has the tables I need to access via the hardcoded name. Basically, each view will have a statement that looks like this..

CREATE VIEW schemaname.tablename as SELECT * FROM targetdbname.schemaname.tablename

Example:

The target database name that is hardcoded is called ProdDBV1 and the Source DB you have is named ProductDatabaseDatabaseV1, schema is dbo and table name is customer

  1. Create the database called ProdDBV1 using SSMS or script.
  2. CREATE VIEW dbo.customer as SELECT * FROM ProductDatabaseDatabaseV1.dbo.customer

If you can enumerate each table in your "source" database and then create the DDL as above. If you want I can update this posting with a code example. (using the sp_msforeachtable procedure if possible)

Tor
  • 1,522
  • 3
  • 16
  • 26
Charles
  • 156
  • 1
  • 4
  • Say you have an SSRS report that calls a SP where one of the parameters is the database name (say you have 10 different customer database) - I don't think this approach would get you away from using dynamic sql in the SP (ie: sp_executesql @sql), where @sql has the database name concatenated in at runtime.....would it? – tbone Apr 05 '16 at 15:27
  • 2
    This also won't handle functions. :( – tbone May 25 '16 at 20:22
  • How is this answer accepted when you said, "... our processes don't allow us use db02 as a name of database." Are you allowed to have a database called db02 that has no data but a bunch of views pointing to some other database? – JeffO Jun 12 '20 at 11:39
12

I had a similar issue.
Solved with this workaround, using synonyms.

Short version: You flood your database with a synonym of every object you'll ever need to reference. Later you re-create every synonym with the other database name.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
maxcastaneda
  • 139
  • 1
  • 3
  • 2
    Wow... folks sure are picky here. Max provided a link to an essentially correct answer and it would appear to have been voted down because it provided a link instead of a written out answer? – Jeff Moden Dec 30 '14 at 02:15
  • 33
    And when the blog dies and goes away in a few years? – David Roussel Feb 20 '15 at 16:51
  • 5
    @DavidRoussel in that case you use web archive :-) https://web.archive.org/web/20150502091442/http://www.baud.cz/blog/database-alias-in-microsoft-sql-server – Mladen Mihajlovic Dec 02 '15 at 03:17
  • 36
    It's generally accepted that answers should be answers, and not links to pages that might contain relevant information. See: http://meta.stackexchange.com/a/8259 – David Roussel Dec 04 '15 at 10:33
  • 4
    Thanks for the feedback, @DavidRoussel ...Now that you mention it, I have run into the problem of broken links before and I get it now. Thanks for the explanation. As a bit of a sidebar, it's really frustrating to run into broken links in Microsoft documentation (it's a common problem) so I doubly get it. Thanks, again. – Jeff Moden Aug 30 '19 at 01:49
  • 1
    The _workaround_ link is broken. – intrepidis Jun 20 '23 at 13:14
5

Here's a stored proc to do it. Simply add it to your database and call it with the target database. It will create synonyms for all tables in the target database, and create the schemas if they don't exist. I've left a commented out section in case someone knows of a way to get the create schemas working without a cursor.

CREATE PROCEDURE CreateSynonymsForTargetDatabase (
    @databaseName sysname
)
AS BEGIN
DECLARE @TSQL nvarchar(max) = N''
DECLARE @rn char(2),
    @SchemaName sysname;

    SET @rn = char(13) + char(10)   

    CREATE TABLE #DBSynonym(        
        [Schema] sysname NOT NULL,
        [Table] sysname NOT NULL
    )

    SET @TSQL = N'
        INSERT INTO #DBSynonym ([Schema], [Table])
        SELECT Schemas.name, Tables.name
        FROM [' + @databaseName + '].sys.tables 
        INNER JOIN [' + @databaseName + '].sys.schemas on tables.schema_id = schemas.schema_id      
    '

    EXEC (@TSQL)
    SET @TSQL = N''

    DECLARE MissingSchemasCursor CURSOR
    READ_ONLY
    FOR 
        SELECT newSchemas.[Schema]
        FROM #DBSynonym newSchemas
        LEFT JOIN sys.schemas on newSchemas.[Schema] = schemas.name
        WHERE schemas.schema_id is null
        GROUP BY newSchemas.[Schema]

    OPEN MissingSchemasCursor
    FETCH NEXT FROM MissingSchemasCursor INTO @SchemaName
    WHILE (@@fetch_status <> -1)
    BEGIN
        IF (@@fetch_status <> -2)
        BEGIN
            SET @TSQL = N'CREATE SCHEMA ' + QUOTENAME(@SchemaName) + N';'

            EXEC sp_executesql @TSQL
        END
        FETCH NEXT FROM MissingSchemasCursor INTO @SchemaName
    END
    CLOSE MissingSchemasCursor
    DEALLOCATE MissingSchemasCursor

    /*
    SELECT @TSQL = @TSQL +
        N'
        GO
        CREATE SCHEMA ' + QUOTENAME([Schema]) + N';'
    FROM #DBSynonym newSchemas
    LEFT JOIN sys.schemas on newSchemas.[Schema] = schemas.name
    WHERE schemas.schema_id is null
    GROUP BY newSchemas.[Schema]

    PRINT 'CREATE SCHEMAS : ' + ISNULL(@TSQL,'')
    EXEC sp_executesql @TSQL
    */
    SET @TSQL = N''

    SELECT @TSQL = @TSQL +
        N'
        CREATE SYNONYM ' + QUOTENAME([Schema]) + N'.' + QUOTENAME([Table]) + N'
        FOR ' + QUOTENAME(@databaseName) + N'.' + QUOTENAME([Schema]) + N'.' + QUOTENAME([Table]) + N';'
    FROM #DBSynonym


    EXEC sp_executesql @TSQL
    SET @TSQL = N''

END
GO

Use it as follows :

EXEC CreateSynonymsForTargetDatabase 'targetDbName'
Adam Hardy
  • 377
  • 3
  • 9
1

The question is: how we can create an alias of for database?

I know this is an old post but...

This is why I only use the 2 part naming convention for SQL objects. It allows me to have 2 part synonyms that point to differently named databases depending on what environment I'm in. There are some places where it doesn't work so well but, for the most part, those places are very rare.

As for software that you don't have the source code of and if that software uses the 3 part naming convention, you're probably just out of luck unless you know what the 3 part naming convention is for each object and create a 3 part synonym for each object.

Jeff Moden
  • 3,271
  • 2
  • 27
  • 23
  • Judging from the downvotes, someone has seriously missed the point. Even the OP posted that they ended up using the Synonym method. – Jeff Moden Jul 01 '17 at 13:35
  • I agree, this was exactly what I was looking for, and seems to be what the OP was asking about. – Marcel Marino Jun 06 '19 at 14:01
  • 4
    An old post yes, but I suspect this was downvoted because your answer is more of a discussion and personal preference than a solution. You don't explain your terminology "2 part synonyms" (I assume you mean locally referenced by schema [dbo].[synonym] instead of fully qualified like [server].[database].[schema].[table] ). You don't provide examples or explain why duplicating a synonym in databases is better than directly referencing those tables, or centralizing synonyms on a server. All your explanation does is have someone who is searching for an answer, more confused – Antony Booth Aug 28 '19 at 16:17
0

I found Charles' answer (and the linked workaround in the comment by maxcastaneda) very useful. I followed this approach and it works for me. I have streamlined it a bit and created the following query that brings up all required synonyms to create.

As a prerequisite for this snippet both the original DB and the synonym/alias db have to be on the same server otherwise in case you use linked server or so you have to modify it a bit. It should be fairly easy to put this into a small sp to update the synonyms automatically.

USE <SYNONYMDB>
SELECT 
'[' + TABLE_NAME + ']', 
'[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']',
'IF EXISTS (SELECT * FROM sys.synonyms WHERE name = ''' + TABLE_NAME + ''') DROP SYNONYM ['+ TABLE_NAME + '];   CREATE SYNONYM [' + TABLE_NAME + '] FOR <ORIGINALDB>.' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']' AS SynonymUpdateScript FROM <ORIGINALDB>.INFORMATION_SCHEMA.TABLES

Don't forget to enter you Db names at the <...> spots.

Just copy the content of the SynonymUpdateScript Column and execute it in the synonym DB - or create a stored procedure for this task.

Be aware there is an issue if you have views in place that refer to tables or other db objects without the 2 part naming convention. Those synonyms won't work. You should fix this in the original objects / views.

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Magier
  • 437
  • 1
  • 6
  • 18
0
  1. Go to the Database you wish to create Alias,

  2. Create an Alias Folders table with the preferred design,

  3. Go to unique IDs's table and check the last code sequence for the table created.

    For example, if the last code is 10, then update it to 11.

  4. Open Cabinets table and go right at the bottom and create the name of the Alias cabinet you want.

Pang
  • 9,564
  • 146
  • 81
  • 122
Suzie
  • 1
-1

You can create an alias from 'SQL Server Configuration Manager' under Configuartion Tool in SQL Server Folder.

Detailed source : http://www.mssqltips.com/sqlservertip/1620/how-to-setup-and-use-a-sql-server-alias/

http://technet.microsoft.com/en-us/library/ms190445.aspx

BAdmin
  • 927
  • 1
  • 11
  • 19
  • 3
    Same thing here. Correct me if I'm wrong but that would appear to be an alias for a server rather than an alias for a database. – Jeff Moden Apr 30 '14 at 00:30