Добавление max (значение) +1 в новую строку, это может быть проблемой? - PullRequest
2 голосов
/ 15 июля 2011

В таблице SQL Server у меня есть следующие 2 столбца:

RowId : первичный ключ, числовой, идентификационный столбец и автоматическая вставка.
MailId : без ключа, числовой, без идентификатора и без автоматической вставки.

Идентификатор почты может быть повторен. В случае нового MailId я проверю max (MailId) +1 и вставлю его в новую строку, а в случае дублирования значение будет приходить в качестве параметра.

Логика выглядит хорошо, но здесь есть одна проблема, которую я только что рассматривал (хотя степень достоверности очень мала) В то же время могут быть два разных новых запроса MailId. Может ли это вызвать логическую ошибку? Например, когда проверено, что код max (MailId) +1 был 101, и я сохранил его в переменной, но это может произойти до того, как следующая вставка будет выполнять новую запись, вставленную в таблицу. Теперь max (MailId) +1 в таблице будет 102, но значение в переменной будет 101?

Любое предложение, пожалуйста, я хочу также контролировать вероятность этой ошибки.

EDIT

(я не использую identity (1,1), потому что я также должен передать в него пользовательские значения)

Ответы [ 2 ]

6 голосов
/ 15 июля 2011

Зачем использовать пользовательское поле Identity, если в SQL Server уже есть такое замечательное поле?

Просто используйте INT Identity (1,1) для поля идентификатора, и оно будет автоматически увеличиваться при каждом добавлении строки. Он также обрабатывает параллелизм гораздо лучше, чем все, что вы можете реализовать вручную.

EDIT:

Пример значения идентификатора вручную:

SET IDENTITY_INSERT MyTable ON

INSERT INTO MyTable (IdField, Col1, Col2, Col3,...)
VALUES
(1234, 'Col1', 'Col2', 'Col3',...)

SET IDENTITY_INSERT MyTable OFF

Вам необходимо включить явный список полей для INSERT.

1 голос
/ 15 июля 2011

Используйте OUTPUT на вашей вставке, чтобы убедиться, что вы выбрали правильное значение. Если вы вставите, а затем выберете MAX, вполне возможно, что кто-то может «подкрасться» и в итоге получится дублирование. То есть вы вставляете MAX + 1, в то время как кто-то еще вставляет MAX + 1, затем вы выбираете MAX, а они выбирают MAX, у вас обоих одинаковое значение. Принимая во внимание, что если вы ВСТАВИТЕ и используете OUTPUT, вы будете уверены, что вы уникальны. Это редко является проблемой, но если у вас много активности, это может произойти (если судить по опыту).

EDIT

USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
    ModifiedDate = GETDATE() 
OUTPUT inserted.BusinessEntityID,
       deleted.VacationHours,
       inserted.VacationHours,
       inserted.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...