在之前有使用过参数化查询来提高程序SQL语句执行效率,但是碰到的问题是:每个sql语句都有对应的参数及对应的参数值,这样就没办法像字符串拼接那样收集语法一次执行从而造成不得不循环来执行参数化的语法。。。不知道各位园友是怎么解决的,还是我在这点上理解有误。
示例:
update gsms_user set state=?0 where enterprise_id=?1 and state!=2
其中有两个参数
在代码中我必须创建对应的parameters并加到DbCommand对象中,如下
private IEnumerable<dynamic> QueryInternal(string commandText, CommandType commandType, params object[] parameters) {
EnsureConnectionOpen();
using (DbCommand command = Connection.CreateCommand())
{
command.CommandText = commandText;
command.CommandType = commandType;
if (this.CommandTimeout > 0)
command.CommandTimeout = this.CommandTimeout;
AddParameters(command, parameters);
…………
}
如果我的update是再循环中,就可能变成循环调用这个方法。但如果我不使用参数化查询,语句变成如下:
update gsms_user set state={0} where enterprise_id={1} and state!=2;
我就可以通过StringBuilder拼接字符串最后再执行语法
你可以提供两段代码来说明下你的问题。
补上示例了,你再看下,谢谢!
@滴答的雨: 可以使用 update gsms_user set state=@newstate where enterprise_id=@id and state!=@state 作为 key ,来缓存已经创建成功的 SqlParameter[] 数组,这样,当你变更传入参数的值后,就可以使用已经缓存的 SqlParameter[] 来赋值就行了。
对于非参数化的方法:update gsms_user set state={0} where enterprise_id={1} and state!={2},当你得到这个更新语句的 format string 后,变更参数的值后,你使用 string.Format() 来给参数赋值。
也就是说,两种方式,都可以先得到一个“表达式”,只是给“表达式”填写值的方法不一样。
@Launcher:
是,
1、参数化可以通过缓存找到对应的参数值。
2、拼接语法也可以通过String.Format()或StringBuilder.AppendFormat()
但是两者有一个不同,拼接语法后最后得到的是"语法1;语法2;语法3;……",这样我一次执行语法就好了,但是参数化的话,尽管我能用缓存找到参数化语句对应的参数值,但是我执行还是得一条一条的去执行,这样就循环下语法了。
@滴答的雨: 你的意思你想在一个 CommandText 中包含多个 SQL 语句吗?换句话说,就是批量更新数据库记录。
@Launcher:
恩,这个意思,呵呵表达上有点歧义。
但是之前在尝试批量更新时又想来个参数化操作,这时候就出现我说的问题了
@滴答的雨: 不使用参数化的时候:
foreach(参数集合)
{
StringBuilder.AppendFormat(“{0}”,参数集合[i]);
}
使用参数的时候:
foreach(参数集合)
{
SqlParameter[] params = 缓存的 SqlParameter[] 克隆;
}
与不使用参数的执行方式不一样的是,需要使用 SqlTransaction 来将多个 SqlCommand 的执行包含在同一个事务中提交。
@Launcher:
参数化查询中以事物的方式执行多个SqlCommand确实是一个办法(缓存的对象会稍多一些(eg:SqlCommand),但这也没办法毕避免),谢谢啦!