在新行中添加 max(value)+1,这会是一个问题吗?

问题描述 投票:0回答:3

在 SQL Server 表中,我有以下 2 列:

RowId:主键、数字、标识列和自动插入。
MailId:非密钥、数字、非身份和非自动插入。

邮件 ID 可以重复。如果是新的 MailId,我将检查 max(MailId)+1 并将其插入到新行中,如果出现重复,值将作为参数出现。

逻辑看起来不错,但这里有一个问题,我只是在考虑(但准确性很低)同时可能有两个不同的新 MailId 请求。这会导致逻辑错误吗?例如,当代码检查 max(MailId)+1 为 101 时,我将其存储在变量中,但可能是在下一个插入语句执行插入表中的新记录之前。现在表中的 max(MailId)+1 将是 102,但变量中的值将是 101 ?

请提出任何建议,我也想控制这个错误的机会。

编辑

(我没有使用identity(1,1),因为我还必须在其中传递自定义值)

sql sql-server sql-server-2005 t-sql
3个回答
6
投票

当 SQL Server 中已有如此出色的自定义滚动

Identity
字段时,为什么还要使用自定义滚动字段?

只需使用

INT Identity (1,1)
作为 ID 字段,每次插入行时它都会自动递增。它还可以比您手动实现的任何东西更好地处理并发性。

编辑:

手动ID值示例:

SET IDENTITY_INSERT MyTable ON

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

SET IDENTITY_INSERT MyTable OFF

您需要包含

INSERT
的显式字段列表。


1
投票

使用插入件上的输出来确保您拥有正确的值。如果您插入然后选择 MAX,则可能有人会“潜入”并最终导致重复。也就是说,你插入MAX + 1,同时其他人插入MAX + 1,然后你选择MAX,他们选择MAX,你们都有相同的值。而如果您 INSERT 并使用 OUTPUT,您将确信您是独一无二的。这很少是一个问题,但如果你有很多活动,它可能会发生(根据经验)。

编辑

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

0
投票

@RiaD 如果您使用 Max(pkIdNoIdentityKey)+1,那么您最好锁定表以进行读取,因为您可能会在插入时出现 PrimaryKey 违规错误。由于 SQL 默认为已提交读,因此如果没有序列化锁,对 Max(pkIdNoIdentityKey)+1 的所有并发读取将获得相同的值,直到您提交所有嵌套事务。

最好在带有身份的表上插入行并使用 Select @newId = Scope_Identity

一切都与范围有关!

https://learn.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql?view=sql-server-ver16

© www.soinside.com 2019 - 2024. All rights reserved.