2

在向自己介绍 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是 a 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 参数”是什么意思?这有关系吗?这是否意味着我没有使用存储过程?长度似乎是可选的,尽管它的解释中没有说明。提供它有好处吗?

如您所见,我对此很陌生,只是想弄清楚它。非常感谢你

4

3 回答 3

4

PDO::PARAM_INT并且PDO::PARAM_STR当传递到时bindParam(),表明驾驶员可以随意忽略。

查看 PDO pg 驱动程序的源代码,似乎除了PDO_PARAM_LOB特殊处理之外,所有类型都被引用为字符串(即在引号之间并传递给 libpq 的PQescapeStringConn函数)

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

于 2013-01-22T19:01:30.390 回答
2
$w_ft = 36; 
...
$sth->bindParam(':w_ft', $theId, PDO::PARAM_INT);

应该

$w_ft = 36; 
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);
于 2013-01-22T15:44:11.757 回答
1

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

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

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

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

$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';

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

$sth->bindValue(':something', 5);
$sth->bindValue(':something_else', $foo->bar());
于 2013-01-22T16:08:16.460 回答