Почему эта хранимая процедура не возвращает правильный идентификатор? - PullRequest
3 голосов
/ 06 августа 2010

Периодически эта хранимая процедура будет возвращать идентификатор, который исчисляется миллионами, тогда как в действительности он должен быть только около 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 (), но оната же проблема.

В базе данных нет триггеров.В первичных ключах есть только индексы, которые 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) 30 июля 2009 13:42:21 Copyright (c) 1988-2005 Microsoft Corporation Standard Edition (64-разрядная версия) для Windows NT 5.2 (сборка 3790: службаПакет 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 ]

2 голосов
/ 06 августа 2010

Я думаю, проблема в том, как вы выполняете свой sp.

declare @i int = 0

EXEC [TestStoredProcedure] '1', @i OUTPUT

select @i

Может быть, вы забыли ключевое слово OUTPUT ...

РЕДАКТИРОВАТЬ: И если это так - используйте SCOPE_IDENTITY (), потому что это лучший способ получить значение id в вашем случае.

1 голос
/ 06 августа 2010

Насколько я понимаю, невозможно определить значение, присвоенное столбцу идентификаторов, до тех пор, пока строка не будет создана, и это включает в себя попытку доступа к нему через предложение OUTPUT.

@@ identity и scope_identity () действительно должны работать. Можете ли вы опубликовать свои образцы, используя этот код?

(Примечание: когда я говорю «мое понимание ...», я имею в виду, что я изучил этот лот на нескольких версиях SQL Server, и я никогда нашел способ сделать это, и, кроме того, я, кажется, вспоминаю, как читал несколько постов и статей за эти годы, в которых говорится, что это невозможно, но эй, я действительно хотел бы ошибаться, поэтому я буду смотреть этот пост .)

...