【问题标题】:T-SQL Scripts to copy all table constraints复制所有表约束的 T-SQL 脚本
【发布时间】:2010-12-04 01:03:44
【问题描述】:

我在本地数据库上创建了许多表并将它们移动到生产数据库。

现在我正在对数据库进行微调,并在我的本地数据库表上创建了许多约束,例如 PK、FK、默认值、索引等。

现在我只想将这些约束复制到生产数据库。有办法吗?

请注意,我的生产数据库表已经填充了一些数据。所以我不能删除并重新创建它们。

【问题讨论】:

    标签: sql tsql ddl


    【解决方案1】:

    如果您不想购买任何工具(它们完全物有所值,顺便说一句),您可以随时查询系统目录视图,并从中提取信息以创建可以在新数据库上执行的脚本。

    在例如的情况下默认约束,此查询显示数据库中所有默认约束的列表:

    SELECT
        dc.name 'Constraint Name',
        OBJECT_NAME(parent_object_id) 'Table Name',
        c.name 'Column Name',
        definition
    FROM 
        sys.default_constraints dc
    INNER JOIN 
        sys.columns c ON dc.parent_object_id = c.object_id 
                      AND dc.parent_column_id = c.column_id
    ORDER BY 
        OBJECT_NAME(parent_object_id), c.name
    

    在此基础上,您当然可以创建一个查询,该查询会发出 T-SQL 语句以在您的目标服务器上重新创建这些默认约束:

    SELECT 
        'ALTER TABLE ' + OBJECT_SCHEMA_NAME(dc.parent_object_id) + '.' + OBJECT_NAME(dc.parent_object_id) + 
        ' ADD CONSTRAINT ' + dc.name + ' DEFAULT(' + definition 
        + ') FOR ' + c.name
    FROM
        sys.default_constraints dc
    INNER JOIN 
        sys.columns c ON dc.parent_object_id = c.object_id 
                      AND dc.parent_column_id = c.column_id
    

    你会得到这样的东西(对于AdventureWorks 示例数据库):

    ALTER TABLE dbo.Store ADD CONSTRAINT DF_Store_rowguid DEFAULT((newid())) FOR rowguid
    ALTER TABLE dbo.Store ADD CONSTRAINT DF_Store_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
    ALTER TABLE dbo.ProductPhoto ADD CONSTRAINT DF_ProductPhoto_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
    ALTER TABLE dbo.ProductProductPhoto ADD CONSTRAINT DF_ProductProductPhoto_Primary DEFAULT(((0))) FOR Primary
    ALTER TABLE dbo.ProductProductPhoto ADD CONSTRAINT DF_ProductProductPhoto_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
    ALTER TABLE dbo.StoreContact ADD CONSTRAINT DF_StoreContact_rowguid DEFAULT((newid())) FOR rowguid
    ALTER TABLE dbo.StoreContact ADD CONSTRAINT DF_StoreContact_ModifiedDate DEFAULT((getdate())) FOR ModifiedDate
    ALTER TABLE dbo.Address ADD CONSTRAINT DF_Address_rowguid DEFAULT((newid())) FOR rowguid
    

    当然,您可以根据自己的喜好调整生成的 T-SQL 输出 - 但基本上,将这些结果从查询复制并粘贴到您的新数据库,然后就可以了。

    当然,对于外键关系 (sys.foreign_keys)、检查约束 (sys.check_constraints)、索引 (sys.indexes 和 sys.index_columns) 等等,也有类似的系统目录视图。

    这有点工作 - 但它可以在您自己的时间完成,并且您将在此过程中学到很多关于 SQL Server 的知识。

    所以这又是一个传统的“制造或购买”决定:-)

    马克

    【讨论】:

      【解决方案2】:

      最好的方法是将所有 DDL 代码存储在源代码管理中。然后使用dbGhost(我最喜欢的)或SQL Compare等工具将其部署到生产环境中

      【讨论】:

      • 我使用 DbGhost 已经 10 年了,它从来没有让我失望,没有它我不会尝试中等规模的 SQL 开发。
      • 另一个我用了很长时间的选项是 AdeptSQL Diff。不是免费的,但它可以进行模式和数据比较,速度非常快,并且可以生成更新脚本并直接从应用程序中运行它们。然而,让您的脚本受到版本控制也很重要。
      【解决方案3】:

      Red Gate 的SQL Compare 是一种流行的非免费方式。

      【讨论】:

        【解决方案4】:

        当然这是一篇旧帖子,但上述所有答案中的脚本都没有列出表模式。所以它没有为我的数据库解决问题。

        这个有,所以它做到了:

        -- ===========================================================
        -- Default Constraints
        -- How to script out Default Constraints in SQL Server 2005+
        -- ===========================================================
        
        -- view results in text, to make copying and pasting easier
        -- drop default constraints
        SELECT
            'ALTER TABLE ' +
            QuoteName(OBJECT_SCHEMA_NAME(sc.id)) + '.' + QUOTENAME(OBJECT_NAME(sc.id)) +
            CHAR(10) +
            ' DROP CONSTRAINT ' +
            QuoteName(OBJECT_NAME(sc.cdefault))
        FROM
            syscolumns sc
            INNER JOIN
            sysobjects as so on sc.cdefault = so.id
            INNER JOIN
            syscomments as sm on sc.cdefault = sm.id
        WHERE
            OBJECTPROPERTY(so.id, N'IsDefaultCnst') = 1
        
        -- create default constraints
        SELECT
            'ALTER TABLE ' +
            QuoteName(OBJECT_SCHEMA_NAME(sc.id)) + '.' + QuoteName(OBJECT_NAME(sc.id)) +
            ' ADD CONSTRAINT ' +
            QuoteName(OBJECT_NAME(sc.cdefault))+
            ' DEFAULT ' +
            sm.text +
            ' FOR ' + QuoteName(sc.name)
            + CHAR(13)+CHAR(10)
        FROM
            syscolumns sc
            INNER JOIN
            sysobjects as so on sc.cdefault = so.id
            INNER JOIN
            syscomments as sm on sc.cdefault = sm.id
        WHERE
            OBJECTPROPERTY(so.id, N'IsDefaultCnst') = 1
        

        我改编自 Donabel Santos 的 blog here

        EDITNB: 确保在删除默认约束之前运行查询的两个部分并保存第二个结果集(即ADD CONSTRAINTs),否则您将无法再次重新创建它们(不,我没有这样做:)

        【讨论】:

          【解决方案5】:

          一个很好的免费微软工具。您可以导出架构和数据。

          Microsoft SQL Server Database Publishing Wizard

          【讨论】:

            【解决方案6】:

            试试 DBSourceTools。 http://dbsourcetools.codeplex.com
            它具有架构比较功能,可帮助您创建更新脚本。
            但请记住,您应该对整个数据库使用源代码控制。
            这就是 DBSourceTools 的设计初衷 - 帮助开发人员将他们的数据库置于源代码控制之下。

            【讨论】:

              猜你喜欢
              • 2011-04-13
              • 2010-09-17
              • 2023-04-04
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-10-23
              • 2020-04-08
              • 1970-01-01
              相关资源
              最近更新 更多