0

我有一个多语句 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。

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

编辑:我故意放弃了 try{} 捕获,因为它与我的问题无关。否则,我只是忘记了插入查询中需要的 IDENTITY_SCOPE(),否则将没有返回值。

4

3 回答 3

3

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

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

string sqlQuery =
    @"INSERT INTO myTable(Name, Number) VALUES (@_Name, @_Number);
      INSERT INTO myOtherTable( ID, FirstName) VALUES ( SCOPE_IDENTITY(), @_First )";
于 2012-12-28T07:44:21.917 回答
0

由于insert语句不返回值,ExecuteScalar()因此无法根据需要返回标识。您可以将inserta与文档select scope_identity()中的示例ExecuteScalar()相结合,以获得我认为您期望的功能。

于 2012-12-28T07:47:42.347 回答
0

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

如果命令的结果集为空,则ExecuteScalar返回 null,并且INSERT语句的结果集实际上是空的,除非您包含OUTPUT子句。

于 2012-12-28T07:50:43.913 回答