Почему @@ IDENTITY или SCOPE_IDENTITY () должны быть DBNull? - PullRequest
1 голос
/ 11 января 2009

(решено: см. Внизу)

У меня есть следующий фрагмент кода:

Protected Sub SqlDataSource1_Inserted(ByVal sender As Object, 
ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs)
Handles SqlDataSource1.Inserted
    affected = CInt(DirectCast(e.Command.Parameters("@affected"), IDbDataParameter).Value)
    newID = CInt(DirectCast(e.Command.Parameters("@newID"), IDbDataParameter).Value)
End Sub

Где @newID определяется следующим образом в строке SQL:

"INSERT INTO x(a,b,c) VALUES (@a,@b,@c); SELECT @affected = @@rowcount, @newID = SCOPE_IDENTITY();

Параметры определяются с помощью ASP.NET следующим образом:

Странная вещь в этом заключается в том, что это работает 90% времени, но время от времени выдает InvalidCastException, говоря, что «Преобразование из типа« DBNull »в тип« Integer »недопустимо». Любые идеи о том, что может быть причиной того, что это значение будет нулевым? У меня не установлены триггеры в таблице, и единственное, что делает мой запрос, - это выполнение простой вставки в 1 таблицу.

Редактировать : На основании приведенных здесь предложений я добавил параметр affected. Я установил точку останова и повлиял на = 1, но все равно получил исключение. Однако потом я понял, что у меня был SELECT @newID до SELECT @affect. Я изменил порядок, и теперь @affered = 0. Так что, похоже, проблема с моим оператором вставки в конце концов. Спасибо за вашу помощь!

Ответы [ 7 ]

8 голосов
/ 11 января 2009

С MSDN

После ВСТАВКИ, ВЫБРАТЬ В, или навалом копия заявления завершена, @@ IDENTITY содержит последнюю личность значение, которое генерируется заявление. Если заявление не влияет на любые таблицы с идентичностью столбцы, @@ IDENTITY возвращает NULL.

Есть ли у вас проверка, чтобы убедиться, что вставка прошла успешно? Вполне возможно, что запись, которую вы пытаетесь вставить, по какой-то причине не может вставить что-либо, поэтому идентификатор равен нулю.

Есть ли триггеры на столе? Возможно, вы получаете идентификатор из процедуры триггера, используя @@ IDENTITY

Я бы предложил использовать SCOPE_IDENTITY () или выходной параметр , чтобы получить идентификатор

4 голосов
/ 11 января 2009

Вы должны использовать SCOPE_IDENTITY() вместо @@IDENTITY в 99,9% случаев. Очень редко у вас возникает ситуация, которая требует чего-то другого, кроме SCOPE_IDENTITY()

@@IDENTITY возвращает последнюю ИДЕНТИЧНОСТЬ значение, полученное в связи, независимо от таблицы, которая произвела значение и независимо от объема из заявления, которое произвело значение. Если у вас есть триггер на таблица, которая вызывает идентичность созданный в другой таблице, вы получите личность, которая была создана последней, даже если это был триггер, который создал его.

SCOPE_IDENTITY() возвращает последнее значение IDENTITY, созданное для соединение и с помощью заявления в та же область, независимо от таблицы это произвело ценность. SCOPE_IDENTITY (), например @@ IDENTITY, вернет последнее значение идентичности создан в текущем сеансе, но это также ограничит это вашим текущим сфера также.

Вы уверены, что в этой таблице нет триггеров аудита (возможно, добавленных вашим администратором базы данных)?

2 голосов
/ 11 января 2009

Различные возможности:

  • INSERT ничего не вставляет (как Эриккаллен сказал)

  • ваше заявление (не показано) вставляет к различным столам, последний из который не имеет идентичности колонка

  • INSERT срабатывает триггер, который вставки к столу без столбец идентичности - попробуйте SCOPE_IDENTITY () вместо

1 голос
/ 05 января 2010

В другой раз, когда это произошло, изменилось

<asp:Parameter Name="newID" Direction="Output" Size="4" />

до

<asp:Parameter Name="newID" Direction="Output" Type="Int32" Size="4" />

исправил проблему для меня. Оказалось, что мой хост включил некоторые требования для более явного объявления.

1 голос
/ 11 января 2009

Вы можете выполнить проверку, чтобы убедиться, что @@ ROWCOUNT> 0.

Также были известные проблемы в прошлых версиях SQL Server с триггерами, влияющими на живучесть @@ IDENTITY. Есть ли у вас триггеры?

0 голосов
/ 29 марта 2011

Вы можете получить неправильные значения при использовании SCOPE_IDENTITY () и @@ IDENTITY . В частности, когда запрос заканчивается выполнением в виде параллельного запроса:

http://support.microsoft.com/default.aspx?scid=kb;en-US;2019779

0 голосов
/ 11 января 2009

Что такое query text... часть? ВСТАВКА, я думаю. Может ли это быть insert ... select, который не нашел ни одной строки?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...