【问题标题】:How to create an alias of database in SQL Server如何在 SQL Server 中创建数据库的别名
【发布时间】:2014-02-12 08:08:40
【问题描述】:

我们有一个大约 10 年前创建的非常旧的软件,我们没有源代码。

该软件在同一个 SQL Server 2012 实例上使用两个数据库,DB01DB02

db01..table1 join db02..table2之类的SQL语句,但主要问题是我们的进程不允许我们使用db02作为数据库名称。

问题是:我们如何为数据库创建别名?

我尝试使用CREATE SYNONYM

CREATE SYNONYM [db02] FOR [db02_new_name];

但它不适用于数据库名称。

请建议如何在不修补二进制文件以更正 SQL 语句的情况下解决此问题。

【问题讨论】:

  • 我不相信你可以。当前的两个答案似乎都忽略了这一点并允许服务器实例使用别名,而SYNONYMs 仅适用于数据库的对象。我不知道有什么方法可以给数据库名称起别名。

标签: sql sql-server database alias synonym


【解决方案1】:

使用您要模拟的名称创建一个数据库。重新调整 DDL 代码生成器,为数据库中的每个表创建一个视图,这些表具有我需要通过硬编码名称访问的表。基本上,每个视图都会有一个看起来像这样的语句..

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

例子:

硬编码的目标数据库名称为ProdDBV1,您拥有的源数据库名称为ProductDatabaseDatabaseV1,架构为dbo,表名称为customer

  1. 使用 SSMS 或脚本创建名为 ProdDBV1 的数据库。
  2. CREATE VIEW dbo.customer as SELECT * FROM ProductDatabaseDatabaseV1.dbo.customer

如果您可以枚举“源”数据库中的每个表,然后按上述方式创建 DDL。如果您愿意,我可以使用代码示例更新此帖子。 (如果可能,使用sp_msforeachtable 过程)

【讨论】:

  • 假设您有一个调用 SP 的 SSRS 报告,其中一个参数是数据库名称(假设您有 10 个不同的客户数据库) - 我认为这种方法不会让您远离使用SP中的动态sql(即:sp_executesql @sql),其中@sql在运行时将数据库名称连接起来.....会吗?
  • 这也不会处理函数。 :(
  • 当您说“......我们的进程不允许我们使用 db02 作为数据库名称”时,如何接受这个答案。您是否允许拥有一个名为 db02 的数据库,它没有数据但有一堆指向其他数据库的视图?
【解决方案2】:

我遇到了类似的问题。
使用同义词解决了这个workaround

短版:您的数据库中充斥着您需要引用的每个对象的同义词。稍后,您使用其他数据库名称重新创建每个同义词。

【讨论】:

  • 哇...这里的人肯定很挑剔。 Max 提供了一个指向基本正确答案的链接,但它似乎已被否决,因为它提供了一个链接而不是书面答案?
  • 当博客在几年后消失并消失?
  • @DavidRoussel 在这种情况下你使用网络存档:-) web.archive.org/web/20150502091442/http://www.baud.cz/blog/…
  • 普遍认为答案应该是答案,而不是指向可能包含相关信息的页面的链接。见:meta.stackexchange.com/a/8259
  • 感谢您的反馈,@DavidRoussel ...既然您提到了它,我之前遇到过链接断开的问题,现在我明白了。感谢您的解释。作为一个侧边栏,在 Microsoft 文档中遇到断开的链接真的很令人沮丧(这是一个常见问题),所以我加倍理解。再次感谢。
【解决方案3】:

这是一个存储过程。只需将其添加到您的数据库并使用目标数据库调用它。它将为目标数据库中的所有表创建同义词,并在它们不存在时创建模式。我留下了一个注释掉的部分,以防有人知道在没有光标的情况下让创建模式工作的方法。

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

如下使用:

EXEC CreateSynonymsForTargetDatabase 'targetDbName'

【讨论】:

    【解决方案4】:

    问题是:我们如何为数据库创建别名?

    我知道这是一篇旧帖子,但是...

    这就是为什么我只对 SQL 对象使用两部分命名约定的原因。它允许我有 2 部分同义词,根据我所处的环境指向不同命名的数据库。有些地方它不能很好地工作,但在大多数情况下,这些地方非常罕见。

    对于您没有源代码的软件,并且如果该软件使用 3 部分命名约定,那么您可能只是不走运,除非您知道每个对象的 3 部分命名约定是什么并创建每个对象的 3 部分同义词。

    【讨论】:

    • 从反对票来看,有人严重错过了重点。甚至 OP 也发布了他们最终使用 Synonym 方法。
    • 我同意,这正是我一直在寻找的,并且似乎是 OP 所要求的。
    • 一个旧帖子是的,但我怀疑这被否决了,因为您的回答更多的是讨论和个人偏好,而不是解决方案。您没有解释您的术语“两部分同义词”(我假设您的意思是由模式 [dbo].[synonym] 本地引用,而不是像 [server].[database].[schema].[table] 那样完全限定)。您没有提供示例或解释为什么在数据库中复制同义词比直接引用这些表或在服务器上集中同义词更好。您所做的所有解释都是有人在寻找答案,更加困惑
    【解决方案5】:

    我发现 Charles 的回答(以及 maxcastaneda 评论中链接的解决方法)非常有用。我遵循了这种方法,它对我有用。我对其进行了一些简化并创建了以下查询,该查询会显示所有需要创建的同义词。

    作为此 sn-p 的先决条件,原始数据库和同义词/别名数据库都必须位于同一服务器上,否则如果您使用链接服务器,或者您必须对其进行一些修改。 将其放入一个小的 sp 中以自动更新同义词应该相当容易。

    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
    

    不要忘记在 <...> 位置输入您的 Db 名称。

    只需复制SynonymUpdateScript 列的内容并在同义词数据库中执行它 - 或为此任务创建一个存储过程。

    请注意,如果您的视图在没有两部分命名约定的情况下引用表或其他数据库对象,则会出现问题。那些同义词是行不通的。您应该在原始对象/视图中解决此问题。

    【讨论】:

      【解决方案6】:
      1. 转到您要创建别名的数据库,

      2. 使用首选设计创建别名文件夹表,

      3. 转到唯一 ID 的表并检查创建的表的最后一个代码序列。

        例如,如果最后一个代码是 10,则将其更新为 11。

      4. 打开 Cabinets 表并直接在底部创建所需的 Alias 文件柜名称。

      【讨论】:

        【解决方案7】:

        您可以从 SQL Server 文件夹中配置工具下的“SQL Server 配置管理器”创建别名。

        详细来源:http://www.mssqltips.com/sqlservertip/1620/how-to-setup-and-use-a-sql-server-alias/

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

        【讨论】:

        • 这里也一样。如果我错了,请纠正我,但这似乎是服务器的别名,而不是数据库的别名。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-26
        • 2012-06-17
        • 1970-01-01
        • 2014-01-22
        • 1970-01-01
        • 2012-09-27
        相关资源
        最近更新 更多