Kar*_*ski 0 sql t-sql identity-column sql-server-2008-r2
查询以获取下一个身份?对于没有删除记录的表,这是可能的:
SELECT TOP 1 EMPID + 1 FROM Employee ORDER BY EMPID DESC
Run Code Online (Sandbox Code Playgroud)
如果有删除的数据,我将如何获得下一个身份?例如,我有一个这样的表:
EMPID NAME
4001 someName
4002 someName
4003 ----------------------- this is deleted
4004 someName
4005 someName
4006 someName
4007 someName
4008 someName
4009 ----------------------- this is deleted
4010 ----------------------- this is deleted
Run Code Online (Sandbox Code Playgroud)
输出必须是4011
Aar*_*and 11
您可以IDENTITY在应用程序表单上可靠地显示值的唯一方法是首先插入它.IDENT_CURRENT当你是唯一一个测试它的人时,它似乎可以帮助你,但我可以向你保证,一旦多个用户使用你的应用程序,这将很快崩溃.这也很容易证明.创建下表:
CREATE TABLE dbo.whatever(ID INT IDENTITY(1,1), blat CHAR(1));
Run Code Online (Sandbox Code Playgroud)
现在,在两个单独的Management Studio窗口中,首先运行此代码,该代码模拟您在表单上显示的内容,如果您按照接受的答案和您所说的"工作":
SELECT IDENT_CURRENT('dbo.whatever');
Run Code Online (Sandbox Code Playgroud)
注意输出(两者都应该是1).这是对的.太远了.
现在,在一个窗口中运行:
INSERT dbo.whatever(blat) SELECT 'x';
SELECT SCOPE_IDENTITY();
Run Code Online (Sandbox Code Playgroud)
输出应该是1(这也是正确的SO FAR).
现在,在另一个窗口中,运行相同的东西,但x改为y.此输出现在2.UH-OH.这与您在表单上显示此用户的内容不符.您还可以通过查看表中有两行来验证,并使用1和2作为IDENTITY值:
SELECT ID, blat FROM dbo.whatever;
Run Code Online (Sandbox Code Playgroud)
执行此操作的正确方法,以及执行此操作的唯一方法是插入行,检索值,然后在表单上显示它.如果您需要预先向他们展示一些代理值(不知道为什么你需要这样做,或者为什么你的最终用户需要知道这个值,无论你什么时候检索它 - 为什么用户关心ID是什么?),然后创建一个单独的表并在IDENTITY那里生成您的值.
CREATE TABLE dbo.dummy_table(ID INT IDENTITY(1,1) PRIMARY KEY);
GO
CREATE TABLE dbo.real_table(ID INT PRIMARY KEY, ...other columns...);
GO
Run Code Online (Sandbox Code Playgroud)
现在,当您想在表单上显示"下一个"ID时,您可以使用以下内容执行此操作:
INSERT dbo.dummy_table DEFAULT VALUES;
SELECT SCOPE_IDENTITY();
Run Code Online (Sandbox Code Playgroud)
然后,当用户填写其余信息时,您可以使用从中检索的值插入dbo.real_table并ID在插入列表中包含该列dbo.dummy_table.请注意,如果用户看到ID并且没有单击"保存",这仍然会有间隙,但该ID现在没有意义,因为它从未进入实际表格 - 并且其他任何人都不可能已经看到它(不像可能发生的事情IDENT_CURRENT,MAX+1和其他错误构思的"先检查价值"技术).
如果您的实际目标是将该书的三个副本插入到另一个表中,则解决方案非常简单,并且仍然需要您先插入该书.假设你有参数来表示书的名称和副本数量(以及我确定的其他参数):
DECLARE @Copies INT, @name NVARCHAR(32);
SELECT @Copies = 3, @name = N'Moby Dick';
Run Code Online (Sandbox Code Playgroud)
现在,我们可以插入dbo.Books表中,并使用输出将多行插入另一个表(dbo.Accession?).无需盲目猜测第一个"下一个"值BookID.
DECLARE @BookID INT;
INSERT dbo.Books(name, copies, whatever...) SELECT N'Moby Dick', 3, ...;
SELECT @BookID = SCOPE_IDENTITY();
INSERT dbo.Accession(AccessionID, BookID)
SELECT rn, @BookID
FROM
(
SELECT TOP (@Copies) rn = ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.columns ORDER BY [object_id]
) AS y;
Run Code Online (Sandbox Code Playgroud)
这使用技巧从目录视图生成多个行,但是Numbers如果有的话,您还可以使用内置表来提高效率(以及限制性较低的权限).