【发布时间】:2010-08-06 14:24:37
【问题描述】:
这个存储过程会间歇性地返回一个数百万的 ID,而它实际上应该只有 400 左右。
set ANSI_NULLS OFF
set QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[TestStoredProcedure]
(
@Title VARCHAR(50),
@ID INT OUTPUT
)
AS
DECLARE @ResultsTable Table(InsertedID INT);
INSERT INTO Table
(
Title
)
OUTPUT INSERTED.ID INTO @ResultsTable
VALUES
(
@Title
);
SELECT @ID = (SELECT TOP 1 InsertedID FROM @ResultsTable);
这个存储过程曾经使用 SCOPE_IDENTITY() 返回 ID,但也有同样的问题。
数据库中没有触发器。只有 SQL Server 自动创建的主键上的索引。根本没有任何表的 ID 与返回的值一样大,所以我不知道这些大数字是从哪里来的。
任何帮助或建议将不胜感激。
编辑: 正如我上面所说,这个存储过程最初是这样使用 SCOPE_IDENTITY() 的:
set ANSI_NULLS OFF
set QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[TestStoredProcedure]
(
@Title VARCHAR(50),
@ID INT OUTPUT
)
AS
INSERT INTO Table
(
Title
)
VALUES
(
@Title
);
SELECT @ID = SCOPE_IDENTITY();
编辑 2:
确切的 SQL 版本是:
Microsoft SQL Server 2005 - 9.00.4230.00 (X64) 2009 年 7 月 30 日 13:42:21 版权所有 (c) 1988-2005 Microsoft Corporation Standard Edition (64-bit) on Windows NT 5.2 (Build 3790: Service Pack 2)
编辑 3:
这就是存储过程的调用方式(旧的经典 ASP,它是一个遗留站点)
set obj_CMD = Server.CreateObject("ADODB.Command")
with obj_CMD
.ActiveConnection = Application("DSN")
.CommandText = "TestStoredProcedure"
.CommandType = adCmdStoredProc
dim txt_title
txt_title = "Some text"
set oParam = .CreateParameter("@Title",adVarChar,adParamInput,50,txt_title)
.Parameters.Append oParam
set oParam = .CreateParameter("@ID",adInteger,adParamOutput)
.Parameters.Append oParam
.Execute
dim ID
ID = .Parameters("@ID").Value
end with
set obj_CMD = nothing
编辑 4:
运行 DBCC CHECKIDENT ('Table') 返回:
检查身份信息:当前身份值“422”,当前列值“422”。 DBCC 执行完成。如果 DBCC 打印错误消息,请联系您的系统管理员。
这符合预期。
【问题讨论】:
-
我从来都不是“top 1”的粉丝。如果您使用 max(InertedID) 代替,您会遇到同样的问题吗?
-
相当肯定
@ResultsTable是矫枉过正 - 应该能够在 OUTPUT 子句中设置@ID -
在表中你有插入发生时间的时间戳吗?如果是这样,您可以 SELECT TOP 1 AutoGeneratedID FROM Table ORDER BY timestampcolumn DESC
-
SQL 2005 的哪个版本(运行
select @@version) -
@mpenrow - 这在多用户环境中不安全
标签: sql sql-server-2005 stored-procedures