我有一个多语句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。
现在,假设我在将代码简化为此示例时没有拼写错误,为什么我在returnID中为正确执行的语句接收空值?当我在查询中单独运行语句时,我没有错误,它返回成功。为什么在此事务中运行它时为null?谢谢!
编辑:由于这与我所拥有的问题无关,所以我故意暂停了这个问题。否则,我只是忘记了在插入查询中需要的IDENTITY_SCOPE(),因为否则将没有返回值。
答案 0 :(得分: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 )";
答案 1 :(得分:0)
由于insert
语句不返回值,ExecuteScalar()
无法根据需要返回标识。您可以将insert
与select scope_identity()
合并到ExecuteScalar()
文档的example中,以获得我认为您期望的功能。
答案 2 :(得分:0)
您似乎假设INSERT INTO myTable(Name, Number) VALUES (@_Name, @_Number)
将返回插入行的ID;你为什么那么想?假设是不正确的,这就是为什么你从ExecuteScalar获得一个空值。
ExecuteScalar返回null,并且INSERT语句的结果集实际上为空,除非您包含OUTPUT子句。