无论指定或给定什么数据类型,bindParam都能正常工作

时间:2013-01-22 15:37:07

标签: php sql postgresql pdo prepared-statement

在向pgSQL准备语句介绍自己的同时,我已成功返回了一些查询的结果。但是,我有几个问题。

给出以下查询:

$w_ft = "36"; 
$sth = $dbh->prepare("SELECT * FROM main_products_common_dimensions WHERE w_ft = :w_ft");
$sth->bindParam(':w_ft', $theId, PDO::PARAM_INT);
$sth->execute();
$result = $sth->fetchAll();

我注意到即使main_products_common_dimensions表中的列是character_varying,如果我使用

,我会得到相同/正确的结果集
$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);

$w_ft = "36"; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_STR);

$w_ft = "36"; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_STR);

也就是说,无论我如何绑定参数_INT_STR或设置变量(整数或字符串),都会正确返回数据。这是正常的行为吗?

http://php.net/manual/en/pdostatement.bindparam.php开始,我看到参数数据类型已解释

  

使用PDO :: PARAM_ *常量的参数的显式数据类型。   要从存储过程返回INOUT参数,请使用按位   OR运算符为data_type设置PDO :: PARAM_INPUT_OUTPUT位   参数。

“从存储过程返回INOUT参数”是什么意思?这有关系吗?这是否意味着我没有使用存储过程?长度似乎是可选的,但在其解释中没有指出。提供它有什么好处吗?

正如你所看到的,我对此很陌生,只是试图理解它。非常感谢你

3 个答案:

答案 0 :(得分:4)

传递给PDO::PARAM_INT

PDO::PARAM_STRbindParam()表示驱动程序可以自由忽略。

查看PDO pg驱动程序source code,除了PDO_PARAM_LOB被特殊处理外,所有类型都被引用为字符串(即引号之间并传递给libpq的PQescapeStringConn功能)

您还应该了解控制在幕后使用的方法的PDO::ATTR_EMULATE_PREPARES属性。当false时,PQprepare()与实际的查询外参数一起使用。如果true,则将参数值注入传递给非参数化PQexec()的SQL中。 从技术上讲,这是完全不同的,因此您可能会在角落情况或错误情况下看到不同的行为,具体取决于此属性。

答案 1 :(得分:2)

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $theId, PDO::PARAM_INT);

应该是

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);

答案 2 :(得分:1)

这是因为postgres在与整数列比较时接受整数引用。

因此,如果您的id列是int,则这些查询的工作方式相同:

SELECT * FROM mytable WHERE id = 1;
SELECT * FROM mytable WHERE id = '1';

PDO::PARAM_*常量所做的是修改对值进行引用/转义的方式,并且与值数据类型无关。如果需要,Php也会进行类型转换。如果选择PDO::PARAM_INT,则告诉DBMS驱动程序$ id的值是一个整数,并且应该将其作为整数转义,因此当它将值放入查询时,它不会在它周围添加引号。 / p>

$id = 1;
$sth = $db->prepare("SELECT * FROM mytable WHERE id = :id");
$sth->bindParam(':id', $id, PDO::PARAM_INT);
// resulting query would be SELECT * FROM mytable WHERE id = 1;

$sometext = "hello";
$sth = $db->prepare("SELECT * FROM mytable WHERE id = :id");
$sth->bindParam(':id', $sometext, PDO::PARAM_INT);
// in this case, $sometext will be casted to an integer, that will result in (int)0
// resulting query would be SELECT * FROM mytable WHERE id = 0;

$sometext = "hello";
$sth = $db->prepare("SELECT * FROM mytable WHERE id = :id");
$sth->bindParam(':id', $sometext, PDO::PARAM_STR);
// in this case, $sometext is already a string, and strings should be quoted
// resulting query would be SELECT * FROM mytable WHERE id = 'hello';

另外,关于bindParam的INOUT参数,如果你不打算使用存储过程的INOUT或OUT参数(例如,传递对函数调用的引用而不是函数内部设置的参数) ),你最好使用bindValue。使用bindValue,您可以将函数或任何常量值的结果作为要绑定的值,您不需要放置变量。

$sth->bindValue(':something', 5);
$sth->bindValue(':something_else', $foo->bar());