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' , $calories , PDO :: PARAM_INT );
9 $sth -> bindValue ( ':colour' , $colour , PDO :: 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
san_77227487
2010-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语句
stonewater
2010-06-24 13:24
获取下错误信息看看是什么错误
san_77227487
2010-06-24 13:32
引用 1 楼 stonewater 的回复: 获取下错误信息看看是什么错误
san_77227487
2010-06-24 13:35
另外,虽然这两条语句是可以合并成一条语句. 但这只是一个测试例子, 我想做的是可以同时运行多条语句的功能
licry01
2010-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_77227487
2010-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……
licry01
2010-06-24 15:38
我试了下,是可以的啊 你是不是绑定参数前忘记了调用sqlite3_prepare(.......................) ????? 要不你用的就是sqlite3_exec 我是下面这样的逻辑: 1.sqlite3_prepare 2.绑定各种参数 3.sqlite3_step 4.sqlite3_finalize
san_77227487
2010-06-24 15:57
引用 6 楼 licry01 的回复: 我试了下,是可以的啊 你是不是绑定参数前忘记了调用sqlite3_prepare(.......................) ????? 要不你用的就是sqlite3_exec 我是下面这样的逻辑: 1.sqlite3_prepare 2.绑定各种参数 3.sqlite3_step 4.sqlite3_finalize
licry01
2010-06-24 16:18
引用 5 楼 san_77227487 的回复: 在执行第三个参数的 index3 = sqlite3_bind_parameter_index(m_stmt, "@values3"); 时,返回给index的值是0, 0是错误的,应该是3 所以这种方法应该也是不行
san_77227487
2010-06-24 16:22
引用 8 楼 licry01 的回复: 引用 5 楼 san_77227487 的回复: 在执行第三个参数的 index3 = sqlite3_bind_parameter_index(m_stmt, "@values3"); 时,返回给index的值是0, 0是错误的,应该是3 所以这种方法应该也是不行 我觉得是你第3个参数绑定有问题, 我这绑一大堆都没有问题 你把跟第3个绑定操作相关的代码贴上来看看
san_77227487
2010-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);
}
licry01
2010-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_77227487
2010-06-24 16:28
其中 system("del db1.sqlite3"); 和sqlite3_open("db1.sdb", &pdb); 这里没写对应,不过没关系,不管这个
san_77227487
2010-06-24 16:30
问题就在下面这一句 index3 = sqlite3_bind_parameter_index(stmt, "@pa3"); 只要 index3 = 3 就对了 但现在返回的是0
licry01
2010-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_77227487
2010-06-24 17:34
非常感谢!!我试试看先
san_77227487
2010-07-09 21:25
不好意思 由于临时被交付一件很赶的任务 所以没时间继续测试这个问题 licry01的方法我试过了,的确可以绑定,但sqlite3_step时有错啊,数据库里的数据没有被update 还是不行,原因未知