Короче говоря, я пытаюсь скопировать данные из одной таблицы в другую почти идентичную таблицу (за исключением ограничений, индексов и изменения точности для десятичного столбца) в пакетах, используя Insert [NewTable] Select Top X * from [Table]
, но некоторые данныеменяется во время копирования. Подробнее читайте здесь.
Почему мы копируем в первую очередь
Мы изменяем точность пары столбцов в нашей самой большой таблице и у нас нет времени в нашем окне развертываниясделать простое изменение заявления. В качестве альтернативы мы решили создать таблицу с новой схемой и копировать данные пакетами в дни, предшествующие развертыванию, чтобы позволить нам просто отбросить старую таблицу и переименовать эту таблицу во время окна развертывания.
Создание сценариев для новых и старых таблиц
Это не те таблицы, которые есть в нашей БД, но они были урезаны для этого вопроса. Фактическая таблица имеет ~ 100 столбцов.
CREATE TABLE [dbo].[Table]
(
[Id] BIGINT NOT NULL PRIMARY KEY NONCLUSTERED IDENTITY,
[ForeignKey1] INT NOT NULL,
[ForeignKey2] INT NOT NULL,
[ForeignKey3] INT NOT NULL,
[Name] VARCHAR(MAX) NOT NULL,
[SomeValue] DECIMAL(14, 5) NULL,
CONSTRAINT [FK_Table_ForeignKeyTable1] FOREIGN KEY ([ForeignKey1]) REFERENCES [ForeignKeyTable1]([ForeignKey1]),
CONSTRAINT [FK_Table_ForeignKeyTable2] FOREIGN KEY ([ForeignKey2]) REFERENCES [ForeignKeyTable2]([ForeignKey2]),
CONSTRAINT [FK_Table_ForeignKeyTable3] FOREIGN KEY ([ForeignKey3]) REFERENCES [ForeignKeyTable3]([ForeignKey3]),
)
GO
CREATE INDEX [IX_Table_ForeignKey2] ON [dbo].[Table] ([ForeignKey2])
GO
CREATE TABLE [dbo].[NewTable]
(
[Id] BIGINT NOT NULL PRIMARY KEY NONCLUSTERED IDENTITY,
[ForeignKey1] INT NOT NULL,
[ForeignKey2] INT NOT NULL,
[ForeignKey3] INT NOT NULL,
[Name] VARCHAR(MAX) NOT NULL,
[SomeValue] DECIMAL(16, 5) NULL
)
SQL, который я написал для копирования данных
DECLARE @BatchSize INT
DECLARE @Count INT
-- Leave these the same --
SET @Count = 1
-- Update these to modify run behavior --
SET @BatchSize = 5000
WHILE @Count > 0
BEGIN
SET IDENTITY_INSERT [dbo].[NewTable] ON;
INSERT INTO [dbo].[NewTable]
([Id],
[ForeignKey1],
[ForeignKey2],
[ForeignKey3],
[Name],
[SomeValue])
SELECT TOP (@BatchSize)
[Id],
[ForeignKey1],
[ForeignKey2],
[ForeignKey3],
[Name],
[SomeValue]
FROM [dbo].[Table]
WHERE not exists(SELECT 1 FROM [dbo].[NewTable] WHERE [dbo].[NewTable].Id = [dbo].[Table].Id)
ORDER BY Id
SET @Count = @@ROWCOUNT
SET IDENTITY_INSERT [dbo].[NewTable] OFF;
END
Проблема
Каким-то образом данные искажаются или изменяютсяв, казалось бы, случайном порядке во время копирования. Большинство (возможно, все) измененных данных, которые мы видели, были для столбца ForeignKey2. И значение, которое мы получаем в новой таблице, кажется случайным, так как в старой таблице его вообще не было. Кажется, не существует какой-либо рифмы или причины, по которой записи влияют либо на
Например, вот одна строка для исходной таблицы и соответствующая строка в новой таблице:
Старая таблица
ID: 204663
FK1: 452
FK2: 522413
FK3: 11190
Имя: в маске
Некоторое значение: 0,0
Новая таблица
ID: 204663
FK1: 452
FK2: 120848
FK3: 11190
Имя: замаскировано, но соответствует старой таблице
Некоторые значения: 0,0
Среда
SQL был запущен в SSMS. База данных является базой данных SQL Azure.