pdo 参数绑定中 where 子句中的错误的解决

pdo 参数绑定中 where 子句中的错误的解决

select * from  admin where 1=1  and admin_name =  '$user_name'

象这句是会出错的,说 rang 什么的参数个数不正确之类的. 我也想过是否是 ' 引号造成的,但在 insert 里是这样的呀. 最后解决是目前的 php5.2 的 pdo 中操作 qlite3 要对 where 子句上的特殊处理,即 where 子句中是不要加 ' 引号.

select * from  admin where 1=1  and admin_name =  $user_name

这样就 ok 了

--------------------------------------------------

http://hi.baidu.com/ichuan/blog/item/0002da228dd1965e9822edbe.html

PDO的参数绑定与postgresql数组类型列的冲突
2010-03-17 16:16
php中可以使用PDO来进行数据库操作,利用PDO提供的参数绑定( PDOStatement::bind*系列函数 ),将SQL语句中的条件部分绑定到php变量上,可以基本防止SQL注入攻击。下边是php.net上的一个例子:

 1  <?php
 2  
/* Execute a prepared statement by binding PHP variables */
 3  
$calories 150;
 4  
$colour 'red';
 5  
$sth $dbh->prepare('SELECT name, colour, calories
 6      FROM fruit
 7      WHERE calories < :calories AND colour = :colour'
);
 8  
$sth->bindValue(':calories'$caloriesPDO::PARAM_INT);
 9  
$sth->bindValue(':colour'$colourPDO::PARAM_STR);
10  
$sth->execute();
11  
?>


PDO中使用的是“冒号”作为占位符,如果你的SQL语句中本身有冒号,PDO就会理解为待绑定参数,查询的时候就会有问题。今天在使用PDO时出现了错误,下边是代码:

1  <?php
2  $dbo 
= new PDO("pgsql:dbname=x""u""p");
3  
$stmt $dbo->prepare('SELECT id, arr[1:4] FROM table1 WHERE id in (3397,3398,3399,3401) limit 10');
4  
$stmt->execute();
5  
var_dump($stmt->fetchAll());
6  
var_dump($stmt->errorInfo());
7  
?>


数据库使用的是postgresql,其中arr是类型为数组的列,我这句是想取出arr数组列的前4个元素,然后输出有错误:

 1  array(0) {
 2  }
 3  array(3) {
 4    [0]=>
 5    string(5) "00000"
 6    [1]=>
 7    int(7)
 8    [2]=>
 9    string(52) "ERROR:  syntax error at or near "$1" at character 72"
10  }


原因就是PDO把 ':4' 理解为了占位符,报出此占位符语法错误(标识符不能以数字开头)。
然后 google 了半天没解决办法,后来在冒号后边加了个空格解决了:

3  $stmt $dbo->prepare('SELECT id, arr[1: 4] FROM table1 WHERE ...

加个空格躲过了PDO的检查,而postgresql依然能正确识别 'arr[1: 4]'  为 'arr[1:4]',所以查询正确了。
--------------------------------------------------
http://dev-bbs.com/t6131303.html
Dev BBS -> 数据库 -> sqlite中这样绑定参数行不行的? - VC/MFC / 数据库 [打印本页]  
san_772274872010-06-24 13:19
 
sql = "update qin_country set values1 = ?1 where group_name = ?2; update qin_country set values2 = ?3 where group_name = ?2; "; (两个语句,用分号隔开)

.........

int error1,error2,error3;
error1 = sqlite3_bind_text(m_stmt, 1, buff1, strlen(buff1), NULL);
error2 = sqlite3_bind_text(m_stmt, 2, buff2, strlen(buff2), NULL);
error3 = sqlite3_bind_text(m_stmt, 3, buff3, strlen(buff3), NULL);

......


如上的代码,error1和error2都返回正确,但error3返回失败.
我估计是因为第三个参数,是在sql语句中的第二句,但绑定参数只能绑定在第一句的范围.

那请问下,我这个问题可以解决吗? 我想同时绑定参数和运行这个由两个语句组成的sql语句

stonewater2010-06-24 13:24
获取下错误信息看看是什么错误


san_772274872010-06-24 13:32
引用 1 楼 stonewater 的回复:
获取下错误信息看看是什么错误

赞助商链接2010-06-24 13:32
 

san_772274872010-06-24 13:35
另外,虽然这两条语句是可以合并成一条语句. 但这只是一个测试例子, 我想做的是可以同时运行多条语句的功能

licry012010-06-24 13:51
试试不用"?" 方式的绑定, 比如

sql = "update qin_country set values1 = @values1 where group_name = @values2; update qin_country set values2 = @values3 where group_name = @values2; ";

第一步:
index = sqlite3_bind_parameter_index(m_stmt, "@values1"); 
第二步:
error1 = sqlite3_bind_text(m_stmt, index, buff1, strlen(buff1), NULL);

 

san_772274872010-06-24 14:02
引用 4 楼 licry01 的回复:
试试不用"?" 方式的绑定, 比如

sql = "update qin_country set values1 = @values1 where group_name = @values2; update qin_country set values2 = @values3 where group_name = @values2; ";

第一步:
index = sqlite3_bi……

licry012010-06-24 15:38
我试了下,是可以的啊
你是不是绑定参数前忘记了调用sqlite3_prepare(.......................) ?????
要不你用的就是sqlite3_exec

我是下面这样的逻辑:
1.sqlite3_prepare
2.绑定各种参数
3.sqlite3_step
4.sqlite3_finalize

san_772274872010-06-24 15:57
引用 6 楼 licry01 的回复:
我试了下,是可以的啊
你是不是绑定参数前忘记了调用sqlite3_prepare(.......................) ?????
要不你用的就是sqlite3_exec

我是下面这样的逻辑:
1.sqlite3_prepare
2.绑定各种参数
3.sqlite3_step
4.sqlite3_finalize

licry012010-06-24 16:18
引用 5 楼 san_77227487 的回复:
在执行第三个参数的 index3 = sqlite3_bind_parameter_index(m_stmt, "@values3"); 时,返回给index的值是0, 0是错误的,应该是3

所以这种方法应该也是不行

san_772274872010-06-24 16:22
引用 8 楼 licry01 的回复:
引用 5 楼 san_77227487 的回复:
在执行第三个参数的 index3 = sqlite3_bind_parameter_index(m_stmt, "@values3"); 时,返回给index的值是0, 0是错误的,应该是3

所以这种方法应该也是不行


我觉得是你第3个参数绑定有问题, 我这绑一大堆都没有问题
你把跟第3个绑定操作相关的代码贴上来看看

san_772274872010-06-24 16:25
以下是我的代码,不行

C/C++ code
 
               


#include " stdafx.h "
#include " sqlite3.h "
#include < windows.h >

void my_test()
{
system( " del db1.sqlite3 " );

int ret;
sqlite3 * pdb = 0 ;
sqlite3_stmt * stmt = 0 ;
char * error = 0 ;
const char * tail = 0 ;

int index1, index2, index3;
const void * value = " asdfadsfasdfjasdfjaksdfaskjdfakdsfaksfja " ;

ret = sqlite3_open( " db1.sdb " , & pdb); // 打开数据库,跟打开文本文件一样
if ( ret != SQLITE_OK )
return ;

ret = sqlite3_exec(pdb, " CREATE TABLE qin_country (GROUP_NAME BLOB PRIMARY KEY, VALUES1 BLOB, VALUES2 BLOB); " , 0 , 0 , & error );
if ( ret != SQLITE_OK )
return ;

ret = sqlite3_exec(pdb, " insert into qin_country values(\'group_1234\',\'55555\',\'xxxxy\'); " , 0 , 0 , & error );
if ( ret != SQLITE_OK )
return ;

char * sql = " update qin_country set values1 = @pa1 where group_name = @pa2; \
update qin_country set values2 = @pa3 where group_name = @pa2; " ;

ret = sqlite3_prepare(pdb, sql,strlen(sql), & stmt, & tail);
if ( ret != SQLITE_OK )
return ;

index1 = sqlite3_bind_parameter_index(stmt, " @pa1 " );
index2 = sqlite3_bind_parameter_index(stmt, " @pa2 " );
index3 = sqlite3_bind_parameter_index(stmt, " @pa3 " );

ret = sqlite3_bind_blob(stmt, index1, value, strlen(( char * )value), SQLITE_STATIC);
ret = sqlite3_bind_blob(stmt, index2, value, strlen(( char * )value), SQLITE_STATIC);
ret = sqlite3_bind_blob(stmt, index3, value, strlen(( char * )value), SQLITE_STATIC);

if ( ret != SQLITE_OK )
return ;

ret = sqlite3_step(stmt);
if ( ret != SQLITE_DONE )
return ;

sqlite3_close(pdb);
}


licry012010-06-24 16:27
我的sql是下面这样的:
INSERT INTO [objects](project_id, display_name,parent_id,operator,sequence_num)  
VALUES(@project_id, @node_name, @pid, @p_uid, (select (ifnull(max(sequence_num),1)+1) from [objects] where parent_id=@pid)) ;
insert into [objects_properties](object_id, prop_id) 
select (select object_id from [objects] where parent_id=@pid and display_name=@node_name and project_id=@project_id), prop_id from [properties] ;


我先看看你的代码吧

san_772274872010-06-24 16:28
其中
system("del db1.sqlite3");
和sqlite3_open("db1.sdb", &pdb);
这里没写对应,不过没关系,不管这个

san_772274872010-06-24 16:30
问题就在下面这一句

index3 = sqlite3_bind_parameter_index(stmt, "@pa3");


只要 index3 = 3 就对了
但现在返回的是0

licry012010-06-24 16:55
呵呵, 不好意思啊, 还真如你说的, 参数在第二个子句中才出现就不行了, 只能出现在第一个子句中!
不错不错, 学习了, 看来以后我还真得要注意这地方的应用了.
我改成下面的就能运行了:
C/C++ code
 
               

void my_test()
{
system( " del db1.sdb " );

int ret;
sqlite3 * pdb = 0 ;
sqlite3_stmt * stmt = 0 ;
char * error = 0 ;
const char * tail = 0 ;

int index1, index2, index3;
const void * value = " asdfadsfasdfjasdfjaksdfaskjdfakdsfaksfja " ;

ret = sqlite3_open( " db1.sdb " , & pdb); // 打开数据库,跟打开文本文件一样
if ( ret != SQLITE_OK )
return ;

ret = sqlite3_exec(pdb, " CREATE TABLE qin_country (GROUP_NAME BLOB PRIMARY KEY, VALUES1 BLOB, VALUES2 BLOB); " , 0 , 0 , & error );
if ( ret != SQLITE_OK )
return ;

ret = sqlite3_exec(pdb, " insert into qin_country values(\'group_1234\',\'55555\',\'xxxxy\'); " , 0 , 0 , & error );
if ( ret != SQLITE_OK )
return ;

char * sql = " select @pa1, @pa2, @pa3 where 0>1; update qin_country set values1 = @pa1 where group_name = @pa2; update qin_country set values2 = @pa3 where group_name = @pa2; " ;
// char *sql = "update qin_country set values1 = @pa1 where group_name = @pa2; update qin_country set values2 = @pa3 where group_name = @pa2; ";
// char *sql = "update qin_country set values1 = @pa1, values2=@pa3 where group_name = @pa2; ";

ret = sqlite3_prepare(pdb, sql,strlen(sql), & stmt, & tail);
if ( ret != SQLITE_OK )
return ;

index1 = sqlite3_bind_parameter_index(stmt, " @pa1 " );
ret = sqlite3_bind_blob(stmt, index1, value, strlen(( char * )value), SQLITE_STATIC);
index2 = sqlite3_bind_parameter_index(stmt, " @pa2 " );
ret = sqlite3_bind_blob(stmt, index2, value, strlen(( char * )value), SQLITE_STATIC);
index3 = sqlite3_bind_parameter_index(stmt, " @pa3 " );
ret = sqlite3_bind_blob(stmt, index3, value, strlen(( char * )value), SQLITE_STATIC);

if ( ret != SQLITE_OK )
return ;

ret = sqlite3_step(stmt);
if ( ret != SQLITE_DONE )
return ;

sqlite3_close(pdb);
}

san_772274872010-06-24 17:34
非常感谢!!我试试看先

san_772274872010-07-09 21:25
不好意思 由于临时被交付一件很赶的任务 所以没时间继续测试这个问题

licry01的方法我试过了,的确可以绑定,但sqlite3_step时有错啊,数据库里的数据没有被update

还是不行,原因未知
posted on 2012-02-04 21:46 clq 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/-clq/archive/2012/02/04/2338541.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值