我必须对现有表进行非规范化并保存已经存在的所有数据。 以前我的表结构是
TABLE A:
[id] INT IDENTITY(1,1)
[name] NVARCHAR(100)
[countryID] INT
TABLE B:
[id] INT IDENTITY(1,1)
[countryName] NVARCHAR(100)
新的TableA结构:
TABLE A:
[id] INT IDENTITY(1,1)
[name] NVARCHAR(100)
[countryName] NVARCHAR(100)
我想知道是否有比这更优雅的解决方案
--BACKUP TABLE TO VARIABLE
DECLARE @backup TABLE (
[Id] INT NOT NULL,
[Name] NVARCHAR (1000) NOT NULL,
[CountryId] INT NULL,
INSERT INTO @backup SELECT * FROM [dbName].[TableA]
--RECREATE THE TABLE WITH NEW STRUCTURE
DROP TABLE [dbName].[TableA]
CREATE TABLE [dbName].[TableA]
(
[Id] INT IDENTITY(1, 1) NOT NULL,
[Name] NVARCHAR (1000) NOT NULL,
[CountryId] NVARCHAR (100) NULL,
CONSTRAINT [PK_TableA] PRIMARY KEY CLUSTERED
(
[Id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
SET IDENTITY_INSERT [dbName].[TableA] ON --Required to save original Id's
--INSERT DATA FROM BACKUP TABLE
INSERT INTO [dbName].[TableA]([Id],[Name],[CountryId])
SELECT
backup.[Id],
backup.[Name],
[dbName].[TableB].[Name],
FROM @backup backup
LEFT JOIN [dbName].[TableB] on backup.[CountyId] = [dbName].[TableB].[Id]
SET IDENTITY_INSERT [dbName].[TableA] ON
答案 0 :(得分:3)
不同的人可能有不同的选择。但是对我来说,我将选择此步骤以进行相同操作-
注意:我会选择Alter Table-A选项,以避免数据丢失的情况下还原表。
答案 1 :(得分:1)
我会对您的解决方案保持谨慎。它不是线程安全的(也就是说,如果其他线程正在修改表,则可能会丢失数据)。如果数据库发生问题,您还冒着丢失备份表的风险-例如,如果数据库在drop
之后但在insert
之前关闭了。
您实际上只是在TableA
中添加了新列。好吧,您可以直接这样做:
alter tableA add column countryName varchar(100);
update a
set countryName = b.countryName
from tableA a join
tableB b
on a.CountyId = b.id;
这两个都应该是数据库中的“安全”操作。在执行它们之前,我仍然会备份生产数据库。但是,它们应该没问题。
一个警告是,如果TableA
确实很大,则更改表可能需要一些时间。在更改生产表之前,您可能需要在开发/登台框中进行测试。