如何使用 SQL 服务器备份和恢复带有外键的单个 table
How to Back up and restore a single table with foreign keys using SQL Server
我在数据库中有一个table:
- 我的表格
其他对 MyTable 的 Id 列有外键约束:
- MyOtherTable1
- MyOtherTable2
我需要按原样备份 MyTable。
我要做的任务是数据转换。虽然数据转换在 QA 中有效,但我们的变更控制要求我们必须有一个回滚过程。我不打算实际上必须按原样恢复 table,但我必须证明我可以在更改控制允许我进行更改之前。
本系统为直播下单系统。我无法恢复整个数据库,因为在进行更改和我知道是否必须恢复之间会经历许多订单。
我已经知道如何备份 table。
SELECT * INTO MyTable_Bak FROM MyTable;
但是,恢复 table 无效。我不能这样做:
DELETE FROM MyTable
SELECT * INTO MyTable FROM MyTable_Bak;
以上因外键约束而失败。
我不是在寻找 $oftware。我知道 Red Gate 和其他工具可以做到这一点。
我可用的工具有:
- SQL 管理工作室
- 数据库管理员权限
附加要求
- 恢复后每一列的数据大部分是相同的。 ID,
日期等
- 无法删除table
- 无法更改或删除 MyOtherTable1 或 MyOtherTable2 中的行。
注意:对于这么详细的一道题,我在写题的时候一个一个地检测了这个问题的小部分,然后分别解决了每个问题。我是保留问题并自己回答还是删除?由于我没有找到类似的问答,所以我会保留它。
第 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?
我在数据库中有一个table:
- 我的表格
其他对 MyTable 的 Id 列有外键约束:
- MyOtherTable1
- MyOtherTable2
我需要按原样备份 MyTable。
我要做的任务是数据转换。虽然数据转换在 QA 中有效,但我们的变更控制要求我们必须有一个回滚过程。我不打算实际上必须按原样恢复 table,但我必须证明我可以在更改控制允许我进行更改之前。
本系统为直播下单系统。我无法恢复整个数据库,因为在进行更改和我知道是否必须恢复之间会经历许多订单。
我已经知道如何备份 table。
SELECT * INTO MyTable_Bak FROM MyTable;
但是,恢复 table 无效。我不能这样做:
DELETE FROM MyTable
SELECT * INTO MyTable FROM MyTable_Bak;
以上因外键约束而失败。
我不是在寻找 $oftware。我知道 Red Gate 和其他工具可以做到这一点。
我可用的工具有:
- SQL 管理工作室
- 数据库管理员权限
附加要求
- 恢复后每一列的数据大部分是相同的。 ID, 日期等
- 无法删除table
- 无法更改或删除 MyOtherTable1 或 MyOtherTable2 中的行。
注意:对于这么详细的一道题,我在写题的时候一个一个地检测了这个问题的小部分,然后分别解决了每个问题。我是保留问题并自己回答还是删除?由于我没有找到类似的问答,所以我会保留它。
第 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 语句组合在一起。
运行 上面创建的两个 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 的更好方法,请告诉我。
可以使用
一种可行的方法是:
- 禁用所有约束或仅禁用特定约束
- 恢复 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?