$desc = 'DESC';
$getRecords = $conn->prepare('SELECT * FROM `courses` ORDER BY `id` :sort LIMIT :limitInc, :limit ');
$getRecords->bindValue(':limit',$limit,PDO::PARAM_INT); // working
$getRecords->bindValue(':limitInc',$limitInc,PDO::PARAM_INT); // working
// *** The line below isn't working ***
$getRecords->bindValue(':sort', $desc ,PDO::PARAM_STR); // not working
$getRecords->execute();
我正在尝试在准备查询中调用$desc
..
致命错误:带有消息的未捕获异常'PDOException' 'SQLSTATE [42000]:语法错误或访问冲突:1064您有 SQL语法错误;查看与您的手册相对应的手册 在''DESC'LIMIT 0附近使用正确语法的MySQL服务器版本, C:\ xampp \ htdocs \ portfolio \ nasiraan \ try \ indexx.php中第5行的'5':89 堆栈跟踪:#0 C:\ xampp \ htdocs \ portfolio \ nasiraan \ try \ indexx.php(89): 抛出PDOStatement-> execute()#1 {main} 第89行的C:\ xampp \ htdocs \ portfolio \ nasiraan \ try \ indexx.php
我确信解决方案是..删除字符串$desc
中的引号...但是如何?
答案 0 :(得分:6)
你不得不使用我担心的文字字符串,因为占位符不能包含关键字,例如排序顺序(等等):
$query = sprintf('SELECT * FROM `courses` ORDER BY `id` %s LIMIT :limitInc, :limit ',
strcasecmp($desc, 'DESC') === 0 ? 'DESC' : 'ASC')
);
$getRecords = $conn->prepare($query);
以这种方式构建查询并不是那么糟糕,因为只有两个选项。
答案 1 :(得分:2)
参数标记只能用于应显示数据值的位置,而不能用于SQL关键字,标识符等。
你不能使用预备声明。
如果您想使用绑定值的简单语法,可以使用
SELECT * FROM `courses` ORDER BY `id`*:sort LIMIT :limitInc, :limit
然后绑定有符号数值。但是这个查询will not be optimized by MySQL。
如果您想“吞下”错误的订单,您可以使用@ Jack的解决方案,但错误的方向指示可能会得到错误的结果。如果订单很重要,您必须检查两个值:
strcasecmp($desc, 'DESC') && strcasecmp($desc, 'ASC') ? error() : $desc;
此外,你可以包装PDO并添加特殊方法prepare_ordered($query, $order);
或更复杂的东西,并在那里进行比较。
或者您可以使用没有问题的外国图书馆。但你必须学习它的API。
P.S。我看到你正在使用预先准备好的声明。
答案 2 :(得分:-1)
我总是扩展PDO并添加一些我自己的便利东西。所以首先你这样扩展:
<?php
//Database class
class db extends Pdo{
public function __construct(){
global $conf;
try
{
parent::__construct('DBTYPE:dbname=DBNAME;host=DBHOST', 'DBUSER', 'DBPASS');
$this->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e){
throw new myPdoException($e);
}
}
public function quest($queryString){
try
{
$query = $this->query($queryString);
return $query;
}
catch(PDOException $e){
throw new myPdoException($e);
}
}
public function doPrepare($queryString, $param){
try
{
$query = $this->prepare($queryString);
$query->execute($param);
return $query;
}
catch(PDOException $e)
{
throw new myPdoException($e);
}
}
public function doPrepareBind($queryString, $param){
try
{
$query = $this->prepare($queryString);
foreach($param as $par){
switch($par[2]):
case 'int':
$query->bindParam($par[0], $par[1], PDO::PARAM_INT);
break;
case 'str':
$query->bindParam($par[0], $par[1], PDO::PARAM_STR);
break;
case 'blob':
$query->bindParam($par[0], $par[1], PDO::PARAM_LOB);
break;
default:
$query->bindParam($par[0], $par[1], PDO::PARAM_STR);
break;
endswitch;
}
$query->execute();
return $query;
}
catch(PDOException $e)
{
throw new myPdoException($e);
}
}
}
class myPdoException extends PdoException{
private $_debug = DB_DEBUG;
public function __construct($e){
parent::__construct($e);
$this->showException();
}
private function showException(){
if($this->_debug){
echo
"<div id='transparant'><div id='error'><br /><br />" .
$this->message
. "<br /><br /><br /></div></div>";
}
else{
echo "<div id='transparant'><div id='error'><br /><br />
Er is iets mis gegaan, probeer later nog eens.<br />Sorry voor het ongemak.
<br /><br /><br /></div></div>";
}
}
}
?>
您在第9行看到父构造函数。您必须添加数据库信息来代替大写字母。
请注意,DBTYPE是您正在使用的数据库服务的类型。可能只是它的mysql。
现在这就是我在消毒一系列字符串时使用它的方法:
//first include db class I made above.
$db = new db();
$query = "INSERT INTO `database`.`users` (`id`, `naam`, `email`, `pass`, `key`, `status`) VALUES (NULL, :name, :mail, :pass, '$key', '0')";
$param = array(
array(':name', $_POST['name']),
array(':mail', $_POST['mail']),
array(':pass', $pass_hash)
);
$query = $db->doPrepareBind($query, $param);
答案 3 :(得分:-1)
$ query ='SELECT * FROM courses
ORDER BY id
'。$ desc。' LIMIT:limit,:limitInc';
$ getRecords = $ conn-&gt; prepare($ query); //将我的查询存储在变量名$ query中,在其中我传递了我的变量..所以现在我不需要绑定它..
$ getRecords-&GT; bindValue( ':限制',$限制,PDO :: PARAM_INT);
$ getRecords-&GT; bindValue( ':limitInc',$ limitInc,PDO :: PARAM_INT);
$ getRecords-&GT;执行();