当我在没有“准备”和“执行”的情况下获取数据时,代码工作正常。例如:
$this->db->query("select {$val} from {$table_name} where username={$username}")->fetch();
但此代码始终返回False
:
$this->db->prepare("select :val from :table_name where username = :username")
->execute(array(':username'=>$username,':val'=>$val,':table_name'=>$this->table_name));
HELP:(
感谢您的回答。现在我的代码在这里看:
$q=$this->db->prepare("select pass from nm_users where username = :username");
return $q->execute(array('username'=>$username));
返回值为True
,但我无法从数据库获取数据。
答案 0 :(得分:2)
不要尝试将PDO用作流畅的界面。你不能这样做:
$db->prepare()->execute();
原因是只有当函数保证返回一个在这种情况下具有执行方法的对象时,Fluent接口才有效。
但是prepare()在出错时返回false
。值false
不是对象,也没有execute()方法。
您需要在每次prepare()之后和每次执行()之后检查false
:
$stmt = $this->db->prepare("select :val from :table_name where username = :username");
if ($stmt === false) {
$err = $this->db->errorInfo();
error_log($err[2]);
}
$result = $stmt->execute(array(':username'=>$username,':val'=>$val,':table_name'=>$this->table_name));
if ($result === false) {
$err = $stmt->errorInfo();
error_log($err[2]);
}
如果你这样做,你会发现你的prepare()报告了一个错误:
您的SQL语法有错误;查看与您的MySQL服务器版本相对应的手册,以便在“用户”附近使用正确的语法,其中第1行的用户名='bill''
原因是查询参数仅适用于常量值。您不能将它们用于表名,列名,SQL关键字,表达式,值列表等。
我推断:val
也是一个动态列名,而且也不允许这样做。但在这种情况下,它不会导致错误,它只会为返回的每一行替换值为$val
的文字字符串。
换句话说,用参数替换表名是错误的,因为你不能进行像SELECT * FROM 'user'
这样的查询(文字字符串,而不是表名),这就是参数的行为方式。它只是无效的SQL。
但是动态列名称将执行类似SELECT 'val' FROM ...
的查询,这是合法的,但不会从名为val的列中进行选择,它将选择文字字符串常量'val'。
答案 1 :(得分:0)
无法为表名等设置参数,必须在数组中设置而不用冒号:
$dbSelect=$db->prepare("select aField from aTable where username = :username")
$dbSelect->execute(array('username' => $username));
将aField
和aTable
替换为标准str_replace
或类似的。
答案 2 :(得分:-1)
当你准备它时,表名必须包含在查询中,它不能像其他参数一样动态添加。因此,您必须结合使用两种策略来完成查询:
$stmnt=sprintf('select %1$s from %2$s where username=:username',
$val, $this->table_name);
if (FALSE===($query=$this->db->prepare($stmnt)))
exit('Buggy statement: '.$stmnt);
$query->execute(array(':username'=>$username));
不幸的是,这也意味着您必须注意$this->table_name
被正确转义!