如何在mysql中重用已准备好的语句参数

时间:2013-02-21 21:57:45

标签: php mysql mysqli

我有一个(半)简单的MySQL查询,我正在尝试使用(通过php mysqli扩展),我无法弄清楚如何做到这一点。

我的查询看起来像

SELECT DISTINCT Col1 from `table1` where `col2`= ? and `col3`=? 
UNION SELECT DISTINCT Col1 from `table2` where `col2`=(?) and `col3`=(?)

我有两个表,我不想处理合并,我只想重用原来的两个准备好的“?”。我知道在将值插入表格时我可以为此做些什么,但是我在搜索文档方面的努力迄今为止证明是无用的。

我可以这样做吗?

更新

这是我的代码

$query='SELECT DISTINCT enginesizecc FROM `table1`  where year=? and vehicle_make= ? as UNION SELECT DISTINCT enginesizecc from `table2` WHERE year=(?) AND vehicle_make =(?)';     
$stmt=$sql->prepare($query);
echo $sql->error; //I'm in debug mode
$blank='';
if(array_key_exists('year', $_POST)){
    if(array_key_exists('make', $_POST)){
        $stmt->bind_param('ss', $_POST['year'], $_POST['make']);
    }
    else $stmt->bind_param('ss', $_POST['year'], $blank);
}
elseif(array_key_exists('make', $_POST)){
    $stmt->bind_param('ss', $blank, $_POST['make']);
}
else{
    //if(array_key_exists('model', $_POST)) $stmt->bind_param('sss', $blank, $blank);
    $stmt->bind_param('ss', $blank, $blank);
}
$stmt->execute();
$modelItem='';
$stmt->bind_result($modelItem);
$models=array();
while($stmt->fetch()){      
    $models[]=$modelItem;
}
sort($models);
return $models;

我知道我可以将相同的变量绑定两次,但这似乎效率很低。

2 个答案:

答案 0 :(得分:5)

PDO允许您专门命名参数,如此,但MySQLi不支持命名变量:

"SELECT x FROM y WHERE name = :name and key = :key"

在PDO中,您可以在指定其类型后重复使用:name:key。我不是在争论哪个更好,因为你可以在MySQLi中实现同样的目标。

问题在于MySQLi很难坚持“不要重复自己(DRY)”的方法。 (如果您喜欢DRY,请考虑自定义功能。)

这是有些人更喜欢PDO而不是MySQLi的原因,但有一些时髦的解决方法(例如自定义函数中的call_user_func_array等)。

关于你的“效率”评论,重复变量确实没有区别。它将在MySQL API调用中进行两次参数化,但它几乎不会显着影响性能。 PDO在内部参数化而不使用MySQL(除非你明确地让它使用MySQL),并且MySQLi为它进行MySQL API参数化。

答案 1 :(得分:0)

以下是如何将参数绑定到查询的示例。

global  $dbconnection;

    $sql = "INSERT INTO Sales(order_id,client_id,sale_date,status) VALUES (?,?,?,?)";

    if ($stmt = $dbconnection->prepare($sql)) 
    {   
        /* Bind our params */ 
            $stmt->bind_param('iisi',$order_id,$client_id,$today,$status);  
        $stmt->execute();  
        $stmt->close();
    }
    else
    {
        print "ERROR";
    }