Данные изменяются при копировании данных порциями между двумя одинаковыми таблицами - PullRequest
1 голос
/ 06 ноября 2019

Короче говоря, я пытаюсь скопировать данные из одной таблицы в другую почти идентичную таблицу (за исключением ограничений, индексов и изменения точности для десятичного столбца) в пакетах, используя 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...