在SQL Server表中,我有以下两列:
RowId :主键,numaric,标识列和自动插入。
MailId :非密钥,numaric,非身份和非自动插入。
邮件ID可以重复。如果是新的MailId,我将检查max(MailId)+1并将其插入新行,如果重复,则值将作为参数。
逻辑看起来很好,但这是一个问题,我只是在考虑(但是精确度很低)同时可能有两个不同的新MailId请求。这可能导致逻辑错误吗?例如,当代码检查max(MailId)+1为101并且我将其存储在变量中但可能在下一个插入语句之前执行插入表中的新记录。现在表中的max(MailId)+1将是102但变量中的值将是101?
任何建议请我也想控制这个错误机会。
修改
(我没有使用identity(1,1),因为我还必须在其中传递自定义值)
答案 0 :(得分: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 :(得分:1)
在插入上使用OUTPUT以确保您具有正确的值。如果您插入然后选择MAX,则有可能有人“偷偷摸摸”并最终导致重复。也就是说,你插入MAX + 1,同时别人插入MAX + 1然后你选择MAX并选择MAX,你们两个都有相同的值。而如果您插入并使用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