【转】 参数化查询

SQL SERVER在执行查语句时会生成查询计划,并将查询计划缓存在数据库中,如果下次执行相同的SQL 语句时,会利用缓存的执行计划,而不必重新编译生成执行计划。

使用参数化查询,可以提高查询计划的重用率,提高执行效率。这里以 SQL SERVER 2005为例,分析一下SQL SERVER查询的参数化。

在 SQL SERVER 2005中,可以使用以下 SQL SERVER语句查看缓存的执行计划:

1 SELECT usecounts, cacheobjtype, objtype, text
2
3 FROM sys . dm_exec_cached_plans
4
5 CROSS APPLY sys . dm_exec_sql_text ( plan_handle)
6
7 ORDER BY usecounts DESC ;

分析如下查询代码的执行:

1 command.CommandText = "select * from t1 where col1 = ‘abc‘";
2 command.ExecuteNonQuery();
3 command.CommandText = "select * from t1 where col1 = ‘bcd‘";
4 command.ExecuteNonQuery(); 

首先用 DBCC FreeProcCache命令清空缓存,以免其它查询计划的缓存影响分析,然后执行代码,然后查看缓存的计划有两个:

select * from t1 where col2 = ‘abc‘

select * from t1 where col2 = ‘bcd‘

可以看到 SQL SERVER为两个查询分别生成了一个查询计划,使用次数为 1,并没有重用任何查询计划。

但如果我们使用参数化查询方式

1 command.CommandText = "select * from t1 where col1 = @str";
2 command.Parameters.Add("@str", "abc");
3 command.ExecuteNonQuery();
4 command.Parameters[0].Value = "bcd";
5 command.ExecuteNonQuery(); 

执行后生成的查询计划为

(@strnvarchar(3))Select * From t1 Where col1 = @str

SQL SERVER生成了一个参数化的查询计划,并且这个查询计划的使用次数为 2, SQL SERVER重用了这个查询计划。

当然这样参数化查询并不是最好的,尤其是对字符串类型的参数化查询, SQL SERVER会为不同长度的参数生成不同的查询计划,如:

command.CommandText = "select * from t1 where col1 = @str";
command.Parameters.Add("@str", "abc");
command.ExecuteNonQuery();
command.Parameters[0].Value = "abcd";
command.ExecuteNonQuery(); 

SQL SERVER生成两个查询计划,

(@str nvarchar(4))Select * From t1 Where col1 = @str

(@str nvarchar(3))Select * From t1 Where col1 = @str,

因此使用存储过程是重用查询计划的最好方案,因为 SQL SERVER会将整个存储过程生成的查询计划缓存,无论传入参数是什么,每次都会重用存储过程的查询计划。

时间: 2024-08-27 11:30:56

【转】 参数化查询的相关文章

Sql Server参数化查询之where in和like实现详解

来自:http://www.cnblogs.com/lzrabbit/archive/2012/04/22/2465313.html#wherein 文章导读 拼SQL实现where in查询 使用CHARINDEX或like实现where in 参数化 使用exec动态执行SQl实现where in 参数化 为每一个参数生成一个参数实现where in 参数化 使用临时表实现where in 参数化 like参数化查询 xml和DataTable传参  身为一名小小的程序猿,在日常开发中不可以

使用dapper进行参数化查询

在使用Dapper操作Mysql数据库中我介绍了使用dapper进行CURD基本操作,但在示例代码中参数虽然也是通过@开头,但其实不是真正意义的参数化查询,而是拼接sql,这种方式不利于防止sql注入,所以在Dappe中可以使用DynamicParameters动态参数集合添加参数,从而实现dapper下的参数化查询: 示例代码 using (var connection = new MySqlConnection(connstr)) { //声明动态参数 DynamicParameters P

.NET 出现参数化查询 需要参数但未提供该参数的错误

1.问题的来源 在.NET或者C#中,我们一般执行sql语句的话,推荐使用参数化查询,这样可以避免sql注入的攻击,但是,我在使用参数化查询的时候 出现了以下的错误,详细如下图: 图一这是写sql语句参数化查询的代码 图2 这是MSSQL执行的sql语句 2.问题的原因   出现这种错误的原因在于,在参数化查询的时候,有几个参数的值为null,这样的话,就出现了如图2所示的错误. 为啥会这样了?? 虽然参数的值就是为null,传入数据库中就必须变成DbNull.Value因为此null为c#的,

ADO.NET 参数化查询

使用参数化查询的情景有很多,但最常用的情景是需要用户在查询中进行输入的情况. 有两种方法可供使用.第一,可以讲用户输入嵌入到查询字符串中,例如可能使用.NET Framework中的String.Format函数. 第二种方法是构造一种参数化查询.      在开始时执行如下所示的基本查询: 1 select count(*) from UserInfo 2 3 4 where UserName=‘{0}’ and PassWord=‘{1}’      然后利用用户的输入构造如下查询: 1 s

参数化查询

参数化查询(Parameterized Query 或 Parameterized Statement)是指在设计与数据库链接并访问数据时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值,这个方法目前已被视为最有效可预防SQL注入攻击 (SQL Injection) 的攻击手法的防御方式. 原理: 在使用参数化查询的情况下,数据库服务器不会将参数的内容视为SQL指令的一部份来处理,而是在数据库完成 SQL 指令的编译后,才套用参数运行,因此就算参数中含有恶意的指令,由于已经

参数化查询为什么能够防止SQL注入

很多人都知道SQL注入,也知道SQL参数化查询可以防止SQL注入,可为什么能防止注入却并不是很多人都知道的. 本文主要讲述的是这个问题,也许你在部分文章中看到过这块内容,当然了看看也无妨. 首先:我们要了解SQL收到一个指令后所做的事情: 具体细节可以查看文章:Sql Server 编译.重编译与执行计划重用原理 在这里,我简单的表示为: 收到指令 -> 编译SQL生成执行计划 ->选择执行计划 ->执行执行计划. 具体可能有点不一样,但大致的步骤如上所示. 接着我们来分析为什么拼接SQ

通用权限管理系统底层的参数化查询方法如何使用

通用权限管理系统底层的数据访问方法支持参数化查询. 先前没有使用参数化查询的语句是这样的 string conmmondText = " SELECT A.SITE_ID AID, A.SITE_NAME ANAME, B.SITE_ID BID, B.SITE_NAME BNAME" + " FROM (SELECT 1 AS ID, SITE_NAME, SITE_ID" + " FROM AREA_SUB" + " WHERE A

使用参数化查询防止SQL注入漏洞

参数化查询防止SQL注入漏洞 看别人的登录注册sql语句有没漏洞即可 Where  name='admin' or '1=1' and password='123'; 可以Or '1=1'就是漏洞 http://jingyan.baidu.com/article/27fa7326f53ea746f9271f79.html 以往的防御方式 以前对付这种漏洞的方式主要有三种: l        字符串检测:限定内容只能由英文.数字等常规字符,如果检查到用户输入有特殊字符,直接拒绝.但缺点是,系统 中

参数化查询模糊查询

1.参数化查询模糊查询 sql语句: create proc procegDataAp( @UserName nvarchar(50))asselect * from users where [email protected] 给参数赋值 new SqlParameter("@UserName","%"+TxtsUserName.Text.Trim()+"%") 1 <%@ Page Language="C#" Auto

ACCESS的参数化查询

看论坛上还许多人问及ACCESS被注入的安全问题许多人解决的方法仍然是用Replace替换特殊字符,然而这样做也并没有起到太大做用今天我就把我用ACCESS参数化查询的一些方法和经验和大家分享希望对大家有所启发,有写的不对的地方希望高手们多多指教 ASP.NET 用OleDbCommand的new OleDbParameter创建参数货查询ASP用Command的CreateParameter 方法创建参数化查询(SQL储存过程查询也是用这个方法建立的) ASP.NET C#语法 OleDbPa