为什么此存储过程不返回正确的ID?

时间:2010-08-06 14:24:38

标签: sql sql-server-2005 stored-procedures

这个存储过程会间歇性地返回一个数百万的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标准版(64位)在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打印出错误消息,请与系统管理员联系。

这是预期的。

2 个答案:

答案 0 :(得分:2)

我认为问题在于你如何执行sp。

declare @i int = 0

EXEC [TestStoredProcedure] '1', @i OUTPUT

select @i

也许你忘记了OUTPUT关键字......

编辑:如果是这样的话 - 使用SCOPE_IDENTITY(),因为这是在你的情况下获取id值的更好方法。

答案 1 :(得分:1)

我的理解是,在创建行之前,无法确定分配给标识列的值,包括尝试通过OUTPUT子句访问它。

@@ identity和scope_identity()确实应该有效。您可以使用该代码发布样本吗?

(旁注:当我说“我的理解是......”时,我的意思是我已经在几个版本的SQL Server上查看了这个 lot ,而且我已经从来没有找到办法做到这一点,而且我似乎记得多年来阅读一些帖子和文章,说它不能完成,但是,嘿,我真的想错了,所以我会看这个交。)