2009-01-10 4 views
1

(постановило: см снизу)Зачем было @@ IDENTITY или SCOPE_IDENTITY() быть DBNull?

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

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 @affected. Я переключил порядок, и теперь @affected = 0. Так что все-таки проблема с моей инструкцией insert. Спасибо за вашу помощь!

+1

Существуют ли какие-либо триггеры на целевой таблице? – cmsjr

+0

Вам нужно опубликовать весь запрос. – Portman

+0

Когда возникла ошибка, была ли строка вставлена ​​в таблицу? –

ответ

7

От MSDN

После INSERT, SELECT INTO, или насыпной копия заявление завершено, @@ IDENTITY содержит последнее значение , которое генерируется оператором . Если в заявлении не было , это повлияет на любые таблицы с идентификатором столбцов, @@ IDENTITY возвращает NULL.

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

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

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

+0

Вы можете проверить @@ rowcount, чтобы увидеть, были ли какие-либо строки фактически изменены. – DavGarcia

+0

Если вы используете SQL Server 2005, то также существует предложение OUTPUT - http://blogs.msdn.com/sqltips/archive/2005/06/13/OUTPUT_clause.aspx –

0

Что такое query text...? Я уверен, INSERT. Может ли быть insert ... select, который не нашел ни одного ряда?

2

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

  • ВСТАВИТЬ ничего не вставить (как erikkallen сказал)

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

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

1

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

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

+0

Нет, никаких триггеров. Спасибо хоть. – ine

4

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

@@IDENTITY возвращает последнее значение IDENTITY производится на соединении, независимо от таблицы, производится значение, и независимо от объема отчета, который произвел значение . Если у вас есть триггер на таблице , которая приводит к тому, что идентификатор будет , созданный в другой таблице, вы получите личность, которая была создана последним, , даже если это был триггер, который создал .

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

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

1

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

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

в

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

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

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

  • Нет связанных вопросов^_^