SCOPE_IDENTITY, @@IDENTITY и IDENT_CURRENT возвращают значение null

#sql-server #vb.net

#sql-сервер #vb.net

Вопрос:

dbo, полные разрешения, локальная база данных SQL Server Express, таблицы, которые я создал и которыми владею.

Я только что вставил строку MLA , и если я сделаю a SELECT * FROM MLA , я получу строку, которую я только что вставил…

 19 2019-04-16 15:02:52.000 Test
 

«19» — это ключ, который является столбцом идентификатора. Поэтому я пытаюсь получить этот ключ с помощью любого из них…

 SELECT SCOPE_IDENTITY()
SELECT IDENT_CURRENT('MLA')
SELECT @@IDENTITY
 

И все они возвращают значение NULL.

Строка была вставлена с помощью этой строки кода:

 DbS.Execute(SQL)
 

где DbS — это активное рабочее соединение с сервером, которое также использовалось для вставки. Затем я пытаюсь получить ключ с помощью этого кода:

 Dim DT as RecordSet
DT = DbS.Open("SELECT IDENT_CURRENT('USAA_ArgusVal_MLA')")
 

Я могу себе представить, что Open создает новую область, которая не объясняет @@IDENTITY

ОБНОВЛЕНИЕ: вот решение, которое было предложено ниже, я просто добавил SELECT в существующий INSERT оператор SQL и изменил .Execute на, используя этот код

 SQL amp;= vbCrLf amp; "SELECT SCOPE_IDENTITY() AS MLAKey"
Dim DI As RecordSet = DbS.Open(SQL)
If DI.Read Then
    MLAKey = DI!MLAKey
Else
    MLAKey = ""
End If
 

Комментарии:

1. что это за тип Dbs. Предположительно, для каждого выполнения открывается новое соединение.

2. DBS — это SQLNativeClient (11 IIRC).

3. Что лежит в основе этого . ЧИСТЫЙ тип данных? Не похоже SqlConnection , например, на то, что у него нет открытого метода, выполняющего строку запроса

4. Да, извините, Execute — это просто прикрытие для DbCommand. ExecuteNonQuery. Что, я полагаю, также является его собственной областью применения.

5. Зачем использовать объекты набора записей ADODB в .NET? Для начала я бы предложил преобразовать в объекты с данными SqlClient. Кроме того, я предпочитаю возвращать SCOPE_IDENTITY() в качестве выходного параметра обратно в вызывающий код. Таким образом, если я захочу повторно выбрать вставленные данные, чтобы обновить экран для пользователя (визуальное подтверждение того, что данные были успешно сохранены), я могу это сделать И вернуть новый идентификатор.

Ответ №1:

Вы могли бы использовать OUPTUT предложение и выполнить insert select как единую операцию:

 INSERT INTO MLA(...)
OUTPUT inserted.identity_column_name
VALUES(...)
 

Ответ №2:

Вероятно, ваше соединение «dbs» имеет некоторый пул соединений.

Напишите SQL INSERT, а затем ВЫБЕРИТЕ identity в том же операторе SQL. Лучшим решением является создание хранимой процедуры для вставки данных, а затем возврата текущего идентификатора.

Комментарии:

1. Обычно я использую ExecuteNonQuery для ВСТАВКИ, могу ли я сделать вставку в dbs. Открыть(…)? На самом деле я никогда раньше не пользовался этим методом.

2. Чтобы быть педантичным, я думаю, вы имели в виду output , что нет return .

3. Это решение работает. Я отредактирую вопрос, чтобы показать, что я сделал.

4. @MauryMarkowitz Нет, пожалуйста, не редактируйте решение в вопросе.