在向自己介绍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参数"?这有关系吗?这是否意味着我没有使用存储过程?长度似乎是可选的,尽管它的解释中没有说明这一点。提供它有好处吗?
正如你所看到的,我对此还很陌生,只是想了解一下。非常感谢
PDO::PARAM_INT
和PDO::PARAM_STR
在传递给bindParam()
时表示驱动程序可以自由忽略。
查看PDO pg驱动程序的源代码,除了PDO_PARAM_LOB
被特殊处理外,所有类型都被引用为字符串(即,在引号之间并传递给libpq的PQescapeStringConn
函数(
您还应该注意PDO::ATTR_EMULATE_PREPARES
属性,该属性控制在后台使用的方法。当false
时,PQprepare()
与实际的查询外参数一起使用。如果是true
,则参数值被注入到传递给非参数化PQexec()
的SQL中。从技术上讲,这是完全不同的,因此根据此属性,您可能会在拐角情况或错误情况下看到不同的行为。
$w_ft = 36;
...
$sth->bindParam(':w_ft', $theId, PDO::PARAM_INT);
应该是
$w_ft = 36;
...
$sth->bindParam(':w_ft', $w_ft, PDO::PARAM_INT);
这是因为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';
此外,关于bindParam
的INOUT参数,如果您不打算使用存储过程的INOUT或OUT参数(例如,传递对函数调用的引用,而不是在函数内部设置(,则可能最好使用bindValue
。使用bindValue
,您可以将函数的结果或任何常数值作为要绑定的值,而不需要放置变量。
$sth->bindValue(':something', 5);
$sth->bindValue(':something_else', $foo->bar());