多语句SQL事务在空参数处失败

本文关键字:参数 失败 语句 SQL 事务 | 更新日期: 2023-09-27 17:49:39

我有一个在SqlTransaction中发生的多语句SQL查询,如下所示:

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未提供"的错误。

现在,假设我在简化代码到这个例子时没有拼写错误,为什么我在正确执行的语句中接收到一个null值?当我在查询中单独运行语句时,我没有得到任何错误,它返回成功。为什么在此事务中运行时为空?谢谢!

编辑:我故意从这里留下了一个try{} catch,因为它与我的问题无关。否则,我就会忘记Insert查询中需要的IDENTITY_SCOPE(),因为否则就不会有返回值。

多语句SQL事务在空参数处失败

ExecuteScalar返回查询(MSDN)返回的结果集中第一行的第一列。您的语句是插入,它不返回任何结果集。

修复示例的最简单方法是在一个命令中运行所有查询,并使用SCOPE_IDENTITY获取插入的id。

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

由于insert语句不返回值,ExecuteScalar()不能返回您想要的身份。您可以将insertselect scope_identity()结合起来,就像ExecuteScalar()文档中的示例一样,以获得我认为您期望的功能。

您似乎假设INSERT INTO myTable(Name, Number) VALUES (@_Name, @_Number)将返回插入行的ID;你为什么这么想?这个假设是不正确的,这就是为什么你从ExecuteScalar得到一个空值。

如果命令的结果集为空,并且INSERT语句的结果集实际上为空,则

ExecuteScalar返回null,除非您包含OUTPUT子句。