public static int ExecuteNonQuery(out int id, DbConnection connection, CommandType commandType, string commandText, params DbParameter[] commandParameters)
{
if (connection == null) throw new ArgumentNullException("connection");
if (string.IsNullOrEmpty(Provider.GetLastIdSql().Trim())) throw new ArgumentNullException(" GetLastIdSql is Null Or Empty" );
// 创建DbCommand命令,并进行预处理
DbCommand cmd = Factory.CreateCommand();
bool mustCloseConnection = false;
PrepareCommand(cmd, connection, (DbTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection);
// 执行命令
int retval = cmd.ExecuteNonQuery();//这里没问题
// 清除参数,以便再次使用.
cmd.Parameters.Clear();
cmd.CommandType = CommandType.Text;
cmd.CommandText = Provider.GetLastIdSql();
System.Diagnostics.Debug.Assert(cmd.ExecuteScalar()==null);//总是返回空
id = int.Parse(cmd.ExecuteScalar().ToString());
m_querycount++;
if (mustCloseConnection)
{
connection.Close();
}
return retval;
}
我运行一个insert语句,前面的运行良好,可是后面的取回自增值就报错了,返回的总是空值。郁闷来了。自己在外面写的时候好好的,放到这里面就不行了。
其它内部方法
private static void PrepareCommand(DbCommand command, DbConnection connection, DbTransaction transaction, CommandType commandType, string commandText, DbParameter[] commandParameters, out bool mustCloseConnection)
{
if (command == null) throw new ArgumentNullException("command");
if (string.IsNullOrEmpty(commandText)) throw new ArgumentNullException("commandText");
// If the provided connection is not open, we will open it
if (connection.State != ConnectionState.Open)
{
mustCloseConnection = true;
connection.Open();
}
else
{
mustCloseConnection = false;
}
// 给命令分配一个数据库连接.
command.Connection = connection;
// 设置命令文本(存储过程名或SQL语句)
command.CommandText = commandText;
// 分配事务
if (transaction != null)
{
if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
command.Transaction = transaction;
}
// 设置命令类型.
command.CommandType = commandType;
// 分配命令参数
if (commandParameters != null)
{
AttachParameters(command, commandParameters);
}
return;
}
public string GetLastIdSql()
{
return "SELECT SCOPE_IDENTITY()";
}
---
//System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("insert into lcs_Sys_Model ([Model_GUID],[Model_Name],[Model_Desp],[Model_IsSys]) values ( 'F3CD1369-58C0-4A1F-AF88-05FCF734E079','name','desp',1 )", new System.Data.SqlClient.SqlConnection(@"Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=officially;Data Source=LCSNB\SQL2K"));
//cmd.Connection.Open();
//cmd.ExecuteNonQuery();
//cmd.Parameters.Clear();
//cmd.CommandText = "SELECT SCOPE_IDENTITY()";
//Console.WriteLine(cmd.ExecuteScalar().ToString());
//cmd.Connection.Close();
这个没问题,他们有啥区别呢?看不出个所以然来。
|
select scope_identity()要和insert同时执行的,不然就出了insert的scope所以就取不到identity了,只能写
insert into ... select scope_identity(); 外面的调用是用ExecuteScalar,而不能分为2次执行 你把语句放在存储过程中,让其SQL一起执行,然后返回IDENTITY // 清除参数,以便再次使用. cmd.Parameters.Clear(); cmd.CommandType = CommandType.Text; cmd.CommandText = Provider.GetLastIdSql(); cmd.CommandText是不能清理了再次使用的,这个是无效的 |
|
10个月前 LuChaoShuai : 可是我后面注释掉的一段代码也是分开写的啊。为什么在那里就能取到最后自增的值呢? 我本来也是在insert语句后面跟上一句的。后来又改掉了。。存储过程现在也暂时不想用。 我就想搞明白为什么不能。楼上的回答,对我注释掉的那掉做何解释。 |
|
10个月前 LuChaoShuai : System.Data.SqlClient.SqlParameter[] parameters = { new SqlParameter("@Model_GUID", SqlDbType.UniqueIdentifier), new SqlParameter("@Model_Name", SqlDbType.NVarChar,50), new SqlParameter("@Model_Desp", SqlDbType.NVarChar,500), new SqlParameter("@Model_IsSys", SqlDbType.Bit) }; parameters[0].Value = new Guid("F3CD1369-58C0-4A1F-AF88-05FCF734E079"); parameters[1].Value = "测试实体模型"; parameters[2].Value = "实体模型描述"; parameters[3].Value = false; string connStr = @"Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=officially;Data Source=LCSNB\SQL2K"; string cmdStr = "insert into LCS_Sys_Model ([Model_GUID],[Model_Name],[Model_Desp],[Model_IsSys]) values ( @Model_GUID,@Model_Name,@Model_Desp,@Model_IsSys)"; System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connStr); System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand(cmdStr); cmd.Connection = conn; foreach (var item in parameters) { cmd.Parameters.Add(item); } cmd.Connection.Open(); cmd.ExecuteNonQuery(); //第一次执行结束 cmd.Parameters.Clear(); cmd.CommandText = "SELECT SCOPE_IDENTITY()"; //System.Diagnostics.Debug.Assert(cmd.ExecuteScalar()==null); Console.WriteLine(cmd.ExecuteScalar().ToString()); //第二次执行结束 cmd.Connection.Close(); Console.WriteLine("第一次测试结束"); Console.Read(); cmd.CommandText = "insert into lcs_Sys_Model ([Model_GUID],[Model_Name],[Model_Desp],[Model_IsSys]) values ( 'F |
|
10个月前 LuChaoShuai : 又长见识了。带参数和不带参数。执行居然还是不一样的。。 |