如何使用 SQL 服务器备份和恢复带有外键的单个 table

How to Back up and restore a single table with foreign keys using SQL Server

我在数据库中有一个table:

其他对 MyTable 的 Id 列有外键约束:

我需要按原样备份 MyTable。

我要做的任务是数据转换。虽然数据转换在 QA 中有效,但我们的变更控制要求我们必须有一个回滚过程。我不打算实际上必须按原样恢复 table,但我必须证明我可以在更改控制允许我进行更改之前。

本系统为直播下单系统。我无法恢复整个数据库,因为在进行更改和我知道是否必须恢复之间会经历许多订单。

我已经知道如何备份 table。

SELECT * INTO MyTable_Bak FROM MyTable;

但是,恢复 table 无效。我不能这样做:

DELETE FROM MyTable
SELECT * INTO MyTable FROM MyTable_Bak;

以上因外键约束而失败。

我不是在寻找 $oftware。我知道 Red Gate 和其他工具可以做到这一点。

我可用的工具有:

附加要求

注意:对于这么详细的一道题,我在写题的时候一个一个地检测了这个问题的小部分,然后分别解决了每个问题。我是保留问题并自己回答还是删除?由于我没有找到类似的问答,所以我会保留它。

从这里回答:http://www.rhyous.com/2017/03/14/back-up-and-restore-a-single-table-with-foreign-keys-using-sql-server/

第 2 部分 - 恢复 table

第 1 步 - 查找外键约束
SELECT Name, Object_Name(parent_object_id) as [Table]
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('MyTable')

结果是这样的:

Name                    Table
FKDDED6AECAD1D93C0      MyOtherTable1
FK166B6670AD1D93C0      MyOtherTable2
第 2 步 - 为每个外键获取 Drop 和 Create

在 SQL Server Management Studio Express 中,我转到上面列表中的每个 table,并执行以下操作:

  • 在数据库下找到外键 |我的数据库 |表 | dbo.MyTable |键
  • 右键单击外键并选择脚本键作为 |拖放并创建到 |剪贴板。
  • 将其粘贴到查询中 window。
  • 删除 USING MyDb 语句并将 DROP 语句与两个 ALTER TABLE 语句分开。
  • 重复下一个外键约束,将 DROP 语句和 ALTER TABLE 语句组合在一起。
第 3 步 - 运行 DROP 语句

运行 上面创建的两个 DROP 语句。

ALTER TABLE [dbo].[MyOtherTable1] DROP CONSTRAINT [FKDDED6AECAD1D93C0]
ALTER TABLE [dbo].[MyOtherTable2] DROP CONSTRAINT [FK166B6670AD1D93C0]
第 4 步 - 恢复 table

我使用此查询从备份中恢复 table。

SELECT * 
FROM MyTable

SET IDENTITY_INSERT dbo.MyTable ON; 

TRUNCATE TABLE MyTable ;

INSERT INTO MyTable (Id, Col1, Col2, Col3) -- Specify all columns here
    SELECT (Id, Col1, Col2, Col3)          -- Specify all columns again here
    FROM MyTable_Bak
第 5 步 - 恢复外键约束

运行 您在步骤 2 中组合在一起的 ALTER TABLE 脚本。

ALTER TABLE [dbo].[MyOtherTable2] WITH CHECK 
    ADD CONSTRAINT [FKDDED6AECAD1D93C0] 
        FOREIGN KEY([MyTableId]) REFERENCES [dbo].[MyTable] ([Id])

ALTER TABLE [dbo].[MyOtherTable2] CHECK CONSTRAINT [FKDDED6AECAD1D93C0]

ALTER TABLE [dbo].[MyOtherTable2]  WITH CHECK 
    ADD CONSTRAINT [FK166B6670AD1D93C0] 
    FOREIGN KEY([MyTableId]) REFERENCES [dbo].[MyTable] ([Id])

ALTER TABLE [dbo].[MyOtherTable2] CHECK CONSTRAINT [FK166B6670AD1D93C0]

您的 table 已恢复。

如果您知道不需要 $oftware 的更好方法,请告诉我。

可以使用回答,也可以disable/enable约束。

一种可行的方法是:

  • 禁用所有约束或仅禁用特定约束
  • 恢复 table(s)
  • 启用所有约束或仅启用特定约束

注意:注意不要在约束列中插入不正确的值,否则您将无法对包含不正确数据的 table 启用约束。 您可以使用下面的脚本来帮助您确定禁用或启用了哪些约束:

SELECT (CASE 
    WHEN OBJECTPROPERTY(CONSTID, 'CNSTISDISABLED') = 0 THEN 'ENABLED'
    ELSE 'DISABLED'
    END) AS STATUS,
    OBJECT_NAME(CONSTID) AS CONSTRAINT_NAME,
    OBJECT_NAME(FKEYID) AS TABLE_NAME,
    COL_NAME(FKEYID, FKEY) AS COLUMN_NAME,
    OBJECT_NAME(RKEYID) AS REFERENCED_TABLE_NAME,
    COL_NAME(RKEYID, RKEY) AS REFERENCED_COLUMN_NAME 
FROM SYSFOREIGNKEYS 
ORDER BY TABLE_NAME, CONSTRAINT_NAME,REFERENCED_TABLE_NAME, KEYNO

您可以在下面找到一个 link 到另一个 post,这将很有用: How can foreign key constraints be temporarily disabled using T-SQL?