Мультизаявление сделка SQL, терпящая неудачу в пустом параметре

У меня есть SQL-запрос мультизаявления, который происходит в SqlTransaction следующим образом:

string sName = "";
string sNumber = "";
string sFirstName = "";

string sqlQuery1 = @"INSERT INTO myTable(Name, Number) VALUES (@_Name, @_Number)";
string sqlQuery2 = @"INSERT INTO myOtherTable( ID, FirstName) VALUES ( @_ID, @_First )";

SqlConnection conn = new SqlConn(***);
conn.Open();
SqlTransaction transaction;

SqlCommand command1 = new SqlCommand(sqlQuery1, conn, transaction);
SqlCommand command2 = new SqlCommand(sqlQuery2, conn, transaction);

command1.Parameters.Add("@_Name", SqlDbType.NVarChar, 255).Value = sName;
command1.Parameters.Add("@_Number", SqlDbType.NVarChar, 255).Value = sNumber;

int? returnedID = (int?)command1.ExecuteScalar();

command2.Parameters.Add("@_ID", SqlDbType.Int).Value = (int)returnedID;  <--- Error
command2.Parameters.Add("@_First", SqlDbType.NVarChar, 255).Value = sFirstName;

command2.ExecuteNonQuery();

transaction.Commit();

В линии я отметил как ошибка, я добираюсь, ошибка во время выполнения о "Параметризированном запросе ожидает параметр _ID, который не поставлялся.

Теперь, принятие, у меня нет опечаток, упрощая мой код до этого примера, почему я получаю нулевое значение в returnedID для правильно выполненного заявления? Когда я просто управляю заявлением самостоятельно в вопросе, я не получаю ошибок, и оно возвращается успешный. Почему пустой указатель, управляя им в этой сделке? Спасибо!

Править: Я намеренно бросил попытку {} выгода от этого, поскольку это не относилось к вопросу, который я имел. Иначе я просто забыл о IDENTITY_SCOPE (), что мне было нужно в Запросе на вставку, так как иначе не будет никакого возвращаемого значения.

0
добавлено отредактировано
Просмотры: 1
de
Вы используете объект SQLTransaction, я предложил бы обернуть код в попытку {} выгода, и в код исключения вам будет нужна сделка. RollBack (); если та сделка терпит неудачу.. для начинающих..
добавлено автор MethodMan, источник

3 ответы

ExecuteScalar returns the first column of the first row in the result set returned by the query (MSDN). Your statement is an insert, it does not return any result set.

Самый легкий способ зафиксировать ваш пример состоит в том, чтобы управлять всеми вопросами в одной команде и использовании SCOPE_IDENTITY получить вставленный id.

string sqlQuery =
    @"INSERT INTO myTable(Name, Number) VALUES (@_Name, @_Number);
      INSERT INTO myOtherTable( ID, FirstName) VALUES ( SCOPE_IDENTITY(), @_First )";
3
добавлено
Конечно, я забыл все о добавлении Scope_Identity() к нему. Спасибо!
добавлено автор Xaniff, источник
@paritosh, you' право ре, @@ИДЕНТИЧНОСТЬ может восстановить, id вставил в различный объем, I' ll фиксируют мой ответ. Спасибо
добавлено автор ybo, источник
@@ИДЕНТИЧНОСТЬ не должна использоваться, использовать scope_identity() вместо этого, это лучше.
добавлено автор paritosh, источник

Вы, кажется, предполагаете, что INSERT INTO myTable (Имя, Число) ЦЕННОСТИ (_Name, _Number) собирается возвратить ID вставленного ряда; почему вы думали бы это? Предположение неправильное, который является, почему вы возвращаете нулевое значение из ExecuteScalar.

ExecuteScalar returns null if the command's result set is empty, and the result set of an INSERT statement is in fact empty, unless you include an OUTPUT clause.

0
добавлено

Since insert statements don't return a value, ExecuteScalar() can't return the identity as you want. You can combine the insert with a select scope_identity() as in the example on the ExecuteScalar() documentation to get the functionality I think you're expecting.

0
добавлено