PostgreSQL+PHP:“从选项卡中选择 *,其中 col in (?)”

发布于 2024-10-10 08:10:16 字数 1029 浏览 1 评论 0原文

以下简短的测试脚本

<?php

define('DBHOST', '/tmp');
define('DBNAME', 'XXX');
define('DBUSER', 'XXX');
define('DBPASS', 'XXX');

$ids = array('OK251562715876', 'OK178469380239');

try {
        $db = new PDO('pgsql:host=' . DBHOST . '; dbname=' . DBNAME, DBUSER, DBPASS, $options);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $sth = $db->prepare('select * from pref_money where id in ( ? )');
        $sth->execute($ids);
        while ($row = $sth->fetch(PDO::FETCH_ASSOC))
                print_r($row);

} catch (Exception $e) {
        exit('Database problem: ' . $e->getMessage());
}
?>

失败并出现错误:

Database problem: SQLSTATE[42P18]: 
Indeterminate datatype: 7 
ERROR:  could not determine data type of parameter $2

如果我删除数组的第二个元素,则它可以正常工作。

有没有办法使绑定适用于具有多个元素的数组?

我知道我可以通过使用 join() 等并省略问号来准备完整的 SQL 语句字符串,但随后我需要额外的努力来防止我的 Web 脚本中的 SQL 注入...

使用 PostgreSQL 8.4.6 和 PHP 5.1。 CentOS 5.5下6

the following short test script

<?php

define('DBHOST', '/tmp');
define('DBNAME', 'XXX');
define('DBUSER', 'XXX');
define('DBPASS', 'XXX');

$ids = array('OK251562715876', 'OK178469380239');

try {
        $db = new PDO('pgsql:host=' . DBHOST . '; dbname=' . DBNAME, DBUSER, DBPASS, $options);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $sth = $db->prepare('select * from pref_money where id in ( ? )');
        $sth->execute($ids);
        while ($row = $sth->fetch(PDO::FETCH_ASSOC))
                print_r($row);

} catch (Exception $e) {
        exit('Database problem: ' . $e->getMessage());
}
?>

fails with the error:

Database problem: SQLSTATE[42P18]: 
Indeterminate datatype: 7 
ERROR:  could not determine data type of parameter $2

If I remove the 2nd element of the array, then it works ok.

Is there maybe a way to make the binding work for array with several elements?

I know that I can prepare a complete SQL statement string by using join() etc. and omiting the question mark, but then I need extra effort to prevent SQL injection in my web script...

Using PostgreSQL 8.4.6 with PHP 5.1.6 under CentOS 5.5

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

贱人配狗天长地久 2024-10-17 08:10:16

PDOStatement::execute() 期望单个参数是参数数组。该数组的每个元素都被视为查询参数。因此,现在 PDO“认为”您传递了两个参数,而您的查询仅包含一个参数。

解决方案:传递一个只有一个元素(参数)的数组,即一个数组:...->execute(array($ids));

PDOStatement::execute() expects a single argument that is an array of parameters. Each element of that array is treated as a query parameter. So right now PDO "thinks" that you pass two parameters while your query contains only one.

Solution: pass an array with only one element (parameter), which is an array: ...->execute(array($ids));

心奴独伤 2024-10-17 08:10:16

使用正确数量的问号构建查询(以匹配数组的长度),然后将数组的内容作为值传递给执行

Build the query with the right number of question marks- to match the length of the array- then pass the contents of the array as the values to execute.

风和你 2024-10-17 08:10:16

如果绑定参数以这种方式工作,那就很方便了,但遗憾的是,事实并非如此。你必须做类似的事情:

$sth = $db->prepare('select * from pref_money where id in (?, ?)');
$sth->execute($ids[0], $ids[1]);

丑陋,可能不是你想要的,但你可以编写一些代码让它稍微友好一些(例如,自动放入正确数量的问号)。

It would be convenient if bound parameters worked this way, but alas, they do not. You'd have to do something like:

$sth = $db->prepare('select * from pref_money where id in (?, ?)');
$sth->execute($ids[0], $ids[1]);

Ugly, and probably not what you want, but you can write some code to make it slightly friendlier (automatically put in the right number of question marks, for example).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文