预编译SQL举例
预编译语句PreparedStatement是 java.sql中的一个接口,继承自Statement 接口。通过Statement对象执行SQL语句时,需要将SQL语句发送给DBMS,由 DBMS先进行编译后再执行。而预编译语句和Statement不同,在创建PreparedStatement对象时就指定了SQL语句,该语句立即发送给DBMS进行编译,当该编译语句需要被执行时,DBMS直接运行编译后的SQL语句,而不需要像其他SQL语句那样先将其编译。引发SQL注入的根本原因是恶意用户将SQL指令伪装成参数传递到后端数据库执行。作为一种更为安全的动态字符串的构建方法,预编译语句使用参数占位符来替代需要动态传入的参数,这样攻击者无法改变SQL语句的结构,SQL语句的语义不会发生改变,即便用户传入类似于前面' or '1'='1这样的字符串,数据库也会将其作为普通的字符串来处理。
2. 预编译sql语句就sql绑定变量吗
1. 认识绑定变量:
绑定变量是为了减少解析的,比如你有个语句这样
select aaa,bbb from ccc where ddd=eee;
如果经常通过改变eee这个谓词赋值来查询,像如下
select aaa,bbb from ccc where ddd=fff;
select aaa,bbb from ccc where ddd=ggg;
select aaa,bbb from ccc where ddd=hhh;
每条语句都要被数据库解析一次,这样比较浪费资源,如果把eee换成“:1”这样的绑定变量形式,无论ddd后面是什么值,都不需要重复解析
Java实现绑定变量的方法:
[java] view plain
PreparedStatement pstmt = con.prepareStatement("UPDATE employees SET salay = ? WHERE id = ?");
pstmt.setBigDecimal(1, 15.00);
pstmt.setInt(2, 110592);
/result statmement: UPDATE employees SET salay = 15.00 WHERE id = 110592
pstmt.executeQuery();
假设要将id从1到10000的员工的工资都更新为150.00元,不使用绑定变量,则:
[java] view plain
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 1");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 2");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 3");
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 4");
....
sql.executeQuery("UPDATE employees SET salay = 150.00 WHERE id = 10000");
使用绑定变量,则:
[java] view plain
PreparedStatement pstmt;
for (id = 1; id < 10000; id )
{
if (null == pstmt)
pstmt = con.prepareStatement("UPDATE employees SET salay = ? WHERE id = ?");
pstmt.setBigDecimal(1, 150.00);
pstmt.setInt(2, id);
pstmt.executeQuery();
}
二者区别在于,不用绑定变量,则相当于反复解析、执行了1w个sql语句。使用绑定变量,解析sql语句只用了一次,之后的9999次复用第一次生成的执行计划。显然,后者效率会更高一些。
2. 什么时候不应该/不必要使用绑定变量
a. 如果你用数据仓库,一条大查询一跑几个小时,根本没必要做绑定变量,因为解析的消耗微乎其微。
b. 变量对优化器产生执行计划有很重要的影响的时候:绑定变量被使用时,查询优化器会忽略其具体值,因此其预估的准确性远不如使用字面量值真实,尤其是在表存在数据倾斜(表上的数据非均匀分布)的列上会提供错误的执行计划。从而使得非高效的执行计划被使用。
3. 绑定变量在OceanBase中的实现
目
前OceanBase中实现了绑定变量,目的主要是为了编程方便,而不是为了降低生成执行计划的代价。为什么呢?因为OceanBase中目前使用的是一
种”静态执行计划“,无论什么Query,执行流程都一样。OB在前端代理ObConnector中实现绑定变量,将用户传入的变量进行
to_string()操作,替代SQL语句中相应的部分,形成一个完整的SQL。然后这个SQL传递给MS,MS按照标准流程来解析和执行。相信不远的
将来,OB将会实现真正意义上的绑定变量,让用户享受到绑定变量带来的好处。
3. sql 存储过程是怎么实现的 简单的例子和解释!
存储过程就是一组保存在数据库中的sql语句,在需要的时候可以调用
最简单的,比如
create procere test as
delete from t_1; ---删除t_1表的所有记录
在sql server查询分析器执行时:
exec test; --执行过程test,删除了表t_1的所有记录
当然,没有人这样使用存储过程,存储过程可以接受参数,处理大量sql语句,并返回结果。
当在编写软件的过程中,碰到需要进行复杂的数据库操作时,可能需要大量的sql语句,这时候可以先在数据库中创建存储过程,将sql语句都写在存储过程里,可以视情况加入参数,也可以返回处理结果。编写软件时,在适当的地方引用并执行这个存储过程就好了,至于怎么引用,不同的软件开发语言有不同的语法。
存储过程是预编译的,这样可以提高执行效率,对于软件代码的维护也有好处
4. SQL语句问题:存储过程定义是什么什么时候用它作用是什么怎样写,来个实例!
定义:存储过程是一组为了完成特定功能的SQL语句集,是利用SQL Server所提供的Transact-SQL语言所编写的程序。作用:将常用或复杂的工作,预先用SQL语句写好并用一个指定名称存储起来, 以后需要数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。什么时候用:提高数据库执行速度,对数据库进行复杂操作,重复使用,安全要求高例子: CREATE PROCEDURE order_tot_amt @o_id int, @p_tot int output AS SELECT @p_tot = sum(Unitprice*Quantity) FROM orderdetails WHERE ordered=@o_id GO
5. sql中带有like时如何使用预编译
like语句实际上就是模糊的字段查询,通常与“%”(一个或多个)结合使用。
举例说明:
sql:SELECT * FROM tablename T WHERE T.name LIKE '%zhang%';
解释:以上语句就就是查询出tablename表中name字段带有“zhang”的所有记录。
备注:存储过程中用"||"表示连接符,用单引号(“'”)表示字符连接。
SELECT * FROM tablename T WHERE T.name LIKE '%'||'zhang'||'%'.
6. sql预编译语句就是不执行,怪怪的,求解,急~~
DataSource dataSource = new DataSource(); // 实例化Datasource
QueryRunner runQuery = new QueryRunner(dataSource);
runQuery.batch(sql,object); // sql : "DELETE FROM english WHERE id = ? " 预编译
Object 是一个二维数组 对应你要删除的值希望有帮助!可以到CSDN,IT实验室,365testing
7. c#怎么预编译SQL语句,就是像Java里面那个PreparedStatement那样的,不知道C#哪个类是对应的
C# 连接各种数据库
sql server数据库 :SqlParameter
eg: SqlParameter sPar=new SqlParameter("@name",value);
8. sql预编译语句就是不执行,怪怪的,求解,急~~
你上面的语句是传参数查询吗?应该是参数没有传进去,下面的语句语法没有错误,但是可以返回的查询结果不是正确的.建议写成封装的,不易SQL注入.
比如:
public DataTable SelectAId(pb_list_of_value prep )
{
sql = "SELECT tstand_code from pb_list_of_value where display_value=@display_value and type =@type order by display_value desc ";
sqlpar = new List<SqlParameter>();
sqlpar.Add(newSqlParameter("@display_value",pb_list_of_value.display_value));
DataTable ds=DBHepler.SQLDBHepler.Search(sql,sqlpar,CommandType.Text);
return ds;
}
加粗部分不换行