SQL预处理语句(Prepared Statements)

许多成熟的数据库都支持预处理语句(Prepared Statements)的概念。它们是什么东西?你可以把它们想成是一种编译过的要执行的SQL语句模板,可以使用不同的变量参数定制它。预处理语句具有两个主要的优点:

查询只需要被解析(或准备)一次,但可以使用相同或不同的参数执行多次。当查询准备好(Prepared)之后,数据库就会分析,编译并优化它要执行查询的计划。对于复杂查询来说,如果你要重复执行许多次有不同参数的但结构相同的查询,这个过程会占用大量的时间,使得你的应用变慢。通过使用一个预处理语句你就可以避免重复分析、编译、优化的环节。简单来说,预处理语句使用更少的资源,执行速度也就更快。

传给预处理语句的参数不需要使用引号,底层驱动会为你处理这个。如果你的应用独占地使用预处理语句,你就可以确信没有SQL注入会发生。(然而,如果你仍然在用基于不受信任的输入来构建查询的其他部分,这仍然是具有风险的)。

正因为预处理语句是如此有用,它成了PDO唯一为不支持此特性的数据库提供的模拟实现。这使你可以使用统一的数据访问规范而不必关心数据库本身是否具备此特性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*
使用预处理语句重复插入数据(1)
此示例演示了一个通过向命名占位符代入一个name和一个value值来执行的INSERT查询
*/
$stmt = $dbh ->prepare( "INSERT INTO REGISTRY (name, value) VALUES (:name, :value)" );
$stmt ->bindParam( ':name' , $name );
$stmt ->bindParam( ':value' , $value ); //插入一行
$name = 'one' ;
$value = 1;
$stmt ->execute(); //使用不同的值插入另一行
$name = 'two' ;
$value = 2;
$stmt ->execute();
/*
使用预处理语句重复插入数据(2)
此示例演示了一个通过向用?表示的占位符代入一个name和一个value值来执行的INSERT查询
*/
$stmt = $dbh ->prepare( "INSERT INTO REGISTRY (name, value) VALUES (?, ?)" );
$stmt ->bindParam(1, $name );
$stmt ->bindParam(2, $value ); // 插入一行
$name = 'one' ;
$value = 1;
$stmt ->execute(); // 使用不同的值插入另一行
$name = 'two' ;
$value = 2;
$stmt ->execute();
/*
通过预处理语句获取数据
此示例演示使用从表单获取的数据为关键值来执行查询获取数据。用户的输入会被自动添加引号,所以这儿不存在SQL注入攻击的危险。
*/
$stmt = $dbh ->prepare( "SELECT * FROM REGISTRY where name = ?" );
if ( $stmt ->execute( array ( $_GET [ 'name' ]))) {
while ( $row = $stmt ->fetch()) {
print_r( $row );
}
}

其实主流的PHP框架都支持Prepared Statements,而且要简单很多。下面是ThinkPHP模型支持的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
实例化User模型
*/
$model = D( 'User' );
/*
定义预处理传入数据
*/
$data [ 'username' ] = 'deeka' ;
$data [ 'password' ] = '123456' ;
/*
数据预处理
*/
if ( $model ->create( $data )){
$model ->add();
}
SQL语句中插入文件路径信息通常涉及到字符串的插入,因为路径信息本质上是一个字符串。为了防止SQL注入攻击,推荐使用参数化查询或预处理语句(Prepared Statements)。以下是一个插入文件路径信息的示例: 假设我们有一个名为`files`的表,其中有一个名为`path`的字段,我们想要插入文件路径`C:/Documents/myfile.txt`到这个表中。 1. 使用参数化查询(以MySQL为例): ```sql INSERT INTO files (path) VALUES (?); ``` 在执行这个语句时,你需要提供一个实际的文件路径作为参数,这通常在应用程序代码中通过使用数据库驱动的API来完成。例如,在Python中使用MySQL Connector时,你可以这样做: ```python import mysql.connector # 连接数据库 conn = mysql.connector.connect(user='username', password='password', host='127.0.0.1', database='database') cursor = conn.cursor() # 准备SQL语句和参数 file_path = 'C:/Documents/myfile.txt' query = "INSERT INTO files (path) VALUES (%s)" cursor.execute(query, (file_path,)) # 提交事务 conn.commit() # 关闭连接 cursor.close() conn.close() ``` 2. 使用预处理语句(以SQL Server为例): ```sql EXEC sp_executesql N'INSERT INTO files (path) VALUES (@p0);', N'@p0 nvarchar(max)', @p0 = N'C:/Documents/myfile.txt'; ``` 在这种情况下,`@p0`是参数的占位符,`N'@p0 nvarchar(max)'`定义了参数的类型,`@p0 = N'C:/Documents/myfile.txt'`则是将实际的文件路径值赋给参数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值