Я написал запрос SQL Server, который обновляет записи, чтобы иметь последовательный номер после разделения на поле. Когда я запускаю его как оператор SELECT, все выглядит великолепно:
DECLARE @RunDetailID INT = 448
DECLARE @JobDetailID INT
SELECT @JobDetailID = [JobDetailID] FROM [RunDetails] WHERE [RunDetailID] = @RunDetailID
SELECT
[OrderedRecords].[NewSeq9],
RIGHT([OrderedRecords].[NewSeq9], 4)
FROM
(
SELECT
[Records].*,
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
FROM
(
SELECT
[MRDFStorageID],
[RunDetailID],
[SortField],
[PieceID],
[Seq9],
[BallotType]
FROM
[MRDFStorage]
JOIN [BallotStyles] ON [MRDFStorage].[SortField] = [BallotStyles].[Style] and [BallotStyles].[JobDetailID] = @JobDetailID
WHERE
[RunDetailID] IN (SELECT [RunDetailID] FROM [RunDetails] WHERE [JobDetailID] = @JobDetailID AND [RunStatusID] <> 0)
) Records
) OrderedRecords
JOIN MRDFStorage ON [OrderedRecords].[MRDFStorageID] = [MRDFStorage].[MRDFStorageID]
WHERE
[MRDFStorage].[RunDetailID] = @RunDetailID
Однако, когда я делаю запрос в команду UPDATE, он начинает пропускать четные числа:
DECLARE @RunDetailID INT = 448
DECLARE @JobDetailID INT
SELECT @JobDetailID = [JobDetailID] FROM [RunDetails] WHERE [RunDetailID] = @RunDetailID
UPDATE
[MRDFStorage]
SET
[Seq9] = [OrderedRecords].[NewSeq9],
[Overlay1] = [OrderedRecords].[NewSeq9],
[Overlay10] = RIGHT([OrderedRecords].[NewSeq9], 4)
FROM
(
SELECT
[Records].*,
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
FROM
(
SELECT
[MRDFStorageID],
[RunDetailID],
[SortField],
[PieceID],
[Seq9],
[BallotType],
CAST([SpecialProcessing] as Int) StartCount
FROM
[MRDFStorage]
JOIN [BallotStyles] ON [MRDFStorage].[SortField] = [BallotStyles].[Style] and [BallotStyles].[JobDetailID] = @JobDetailID
WHERE
[RunDetailID] IN (SELECT [RunDetailID] FROM [RunDetails] WHERE [JobDetailID] = @JobDetailID AND [RunStatusID] <> 0)
) Records
) OrderedRecords
JOIN MRDFStorage ON [OrderedRecords].[MRDFStorageID] = [MRDFStorage].[MRDFStorageID]
WHERE
[MRDFStorage].[RunDetailID] = @RunDetailID
Я попытался специально сосредоточиться на этой части:
[Records].[SortField] + RIGHT('0000' + CAST(ROW_NUMBER() OVER(PARTITION BY [Records].[SortField] ORDER BY [Records].[RunDetailID], [Records].[SortField], [Records].[PieceID]) AS VARCHAR), 4) NewSeq9
Есть ли какой-то побочный эффект, о котором я ничего не знаю?
ОБНОВЛЕНИЕ С ТАБЛИЦЫМИ ОПРЕДЕЛЕНИЯМИ
CREATE TABLE [dbo].[MRDFStorage] (
[MRDFStorageID] INT IDENTITY (1, 1) NOT NULL,
[RunDetailID] INT NOT NULL,
[PieceID] VARCHAR (15) NULL,
[SortField] VARCHAR (20) NULL,
[BallotType] VARCHAR (100) NULL,
[Seq9] VARCHAR (15) NULL,
CONSTRAINT [PK_MRDFStorage] PRIMARY KEY CLUSTERED ([MRDFStorageID] ASC),
CONSTRAINT [FK_MRDFStorage_RunDetails] FOREIGN KEY ([RunDetailID]) REFERENCES [dbo].[RunDetails] ([RunDetailID])
);
CREATE TABLE [dbo].[BallotStyles] (
[BallotStyleID] INT IDENTITY (1, 1) NOT NULL,
[JobDetailID] INT NOT NULL,
[Style] VARCHAR (20) NOT NULL,
CONSTRAINT [PK_BallotStyles] PRIMARY KEY CLUSTERED ([BallotStyleID] ASC)
);
CREATE TABLE [dbo].[RunDetails] (
[RunDetailID] INT IDENTITY (1, 1) NOT NULL,
[JobDetailID] INT NOT NULL,
CONSTRAINT [PK_RunDetails] PRIMARY KEY CLUSTERED ([RunDetailID] ASC)
);
sql-server
update
subquery
window-functions
Крис Шиффхауэр
источник
источник
UPDATE [MRDFStorage]
сUPDATE m
иJOIN MRDFStorage ON ...
сJOIN MRDFStorage m ON ...
я боюсь , что , может быть , UPDATE обновляет некоторые строки больше , чем один раз. Прочитайте эту запись в блоге: Давайте не будем использовать ОБНОВЛЕНИЕ ОТ!Ответы:
Из-за отсутствия данных, которые у вас есть, это немного сложнее, но мне удалось воспроизвести то, что вы видите, если увидите следующее:
Ключевым фактором здесь являются две строки в
BallotStyles
.Вы присоединяетесь к
BallotStyles
самому внутреннему запросу, и с данными, подобными приведенным выше, вы получите дублирующиеся строки для каждой строки вMRDFStorage
. Поскольку вы не используете ни один из столбцов,BallotStyles
вы проверяете только наличие строк, и это можно сделать с помощьюexists
предложения, что, конечно, не создаст дублирующихся строк.источник