在向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参数”是什么意思?这有关系吗?这是否意味着我没有使用存储过程?长度似乎是可选的,但在其解释中没有指出。提供它有什么好处吗?
正如你所看到的,我对此很陌生,只是试图理解它。非常感谢你
答案 0 :(得分:4)
PDO::PARAM_INT
时 PDO::PARAM_STR
和bindParam()
表示驱动程序可以自由忽略。
查看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());