#sql-server #vb.net #sql-insert
Вопрос:
У меня есть таблица со столбцом идентификатора, значение которого я хотел бы получить после ВСТАВКИ. Следующий код, который не использует параметры, работает идеально:
string query = "INSERT INTO aTable ([aColumn]) VALUES (42)";
SqlCommand command = new SqlCommand(query, connection);
command.ExecuteNonQuery();
query = "SELECT CAST(SCOPE_IDENTITY() AS bigint)";
command = new SqlCommand(query, connection);
object identity = command.ExecuteScalar();
Если я изменю ВСТАВНУЮ часть приведенного выше кода для использования параметризованного запроса, ExecuteScalar()
внезапно вернется System.DBNull
значение. Вот как выглядит параметризованный код запроса:
string query = "INSERT INTO aTable ([aColumn]) VALUES (@aColumn)";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@aColumn", 42);
command.ExecuteNonQuery();
Я попытался изменить код SCOPE_IDENTITY , чтобы он использовал выходной параметр и вызывал ExecuteNonQuery()
, но я все равно получаю нулевое значение в параметре out. Я также попытался запустить код для двух разных версий SQL Server (2012 и 2008, оба выпуска Express), снова с тем же результатом.
Есть идеи, что я здесь делаю не так?
Комментарии:
1. Параметризованные запросы, вероятно, заканчиваются вызовом
sp_executesql
. Это выполняется в дочерней области и при выходеSCOPE_IDENTITY()
имеет значение null во внешней области.2. В дополнение к объединению их в один пакет, другим обходным решением было бы прекратить внедрение динамического SQL в ваше приложение и поместить эту логику в хранимую процедуру.
3. Вы также можете попытаться
INSERT INTO aTable(...) OUTPUT Inserted.ID VALUES(.....)
автоматически вывести все вставленные новыеID
значения.4. @MartinSmith Спасибо, это прекрасно объясняет, почему принятый мной ответ работает, а мой код-нет.
Ответ №1:
Попробуйте объединить ВСТАВКУ и ВЫБОР в одном операторе
string query = "INSERT INTO aTable ([aColumn]) VALUES (@aColumn);SELECT CAST(SCOPE_IDENTITY() AS bigint)";
SqlCommand command = new SqlCommand(query, connection);
command.Parameters.AddWithValue("@aColumn", 42);
object identity = command.ExecuteScalar();
Комментарии:
1. Для такого неофита, как я, это кажется удивительным, но вместе с комментарием Мартина Смита это действительно имеет смысл 🙂 В любом случае, большое спасибо!