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
还是不行,原因未知 |