2010-08-06 2 views
3

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

Эта хранимая процедура используется для возврата ID с помощью SCOPE_IDENTITY(), но это был один и тот же вопрос ,

В базе данных нет триггеров. На первичных ключах, которые SQL Server создает автоматически, есть только индексы. Нет никаких таблиц, у которых есть идентификатор где-нибудь рядом с тем, что возвращается, поэтому я понятия не имею, откуда эти большие числа.

Любая помощь или предложения будут оценены.

Edit: Как я уже говорил выше, эта хранимая процедура первоначально использовали 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(); 

Edit 2:
Точная SQL версия:
Microsoft SQL Server 2005 - 9.00.4230.00 (X64) 30.07.2009 13:42:21 Copyright (c) 1988-2005 Microsoft Corporation Standard Edition (64-разрядная версия) в Windows NT 5.2 (сборка 3790: с пакетом обновления 2)

Edit 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 печатал сообщения об ошибках, обратитесь к системному администратору.

Это как и ожидалось.

+0

Я никогда не был поклонником «топ-1». Вы получаете те же проблемы, если вместо этого используете max (InertedID)? –

+0

Довольно уверен, что '@ ResultsTable' является излишним - должен быть в состоянии установить' @ ID' в разделе OUTPUT –

+0

В таблице есть ли временная метка, когда произошла вставка? Если это так, вы можете SELECT TOP 1 AutoGeneratedID из таблицы ORDER BY timestampcolumn DESC – mpenrow

ответ

1

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

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

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

+1

Вы можете получить доступ к новому значению IDENTITY, используя предложение OUTPUT. Но да, SCOPE_IDENTITY() должен выполнить эту работу. – AdaTheDev

+0

У меня никогда не было проблемы с возвратом идентификаторов, используя этот метод - таблица «вставлена» в предложении «OUTPUT» отражает вставленную строку точно так же, как в триггере - см. Документацию MS - http://msdn.microsoft.com/ ан-нас/библиотека/ms177564.aspx. –

+0

Я знаю, что, когда в 2005 году вышел первый, я где-то читал, что выходной параметр не обнаружил столбцы идентификаторов. Возможно, я читал это неправильно, возможно, они написали это неправильно, возможно, с тех пор они исправили это. –

2

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

declare @i int = 0 

EXEC [TestStoredProcedure] '1', @i OUTPUT 

select @i 

Может быть, вы забыли ВЫХОДНОЙ ключевое слово ...

EDIT: А если это так - используйте SCOPE_IDENTITY(), потому что это лучший способ, чтобы получить значение идентификатора в вашем случае.

+0

Ошибка прерывистая, поэтому нет ничего существенного, как ключевое слово output. Я использовал SCOPE_IDENTITY(), когда произошла ошибка, и изменила его на код в вопросе как на попытку работы – DaveC

+0

Попробуйте выполнить DBCC CHECKIDENT, возможно, вы получите дополнительную информацию – gyromonotron

+0

Возможно, это может помочь - http: //connect.microsoft.com/SQLServer/feedback/details/328811/scope-identity-sometimes-returns-incorrect-value – gyromonotron

Смежные вопросы