使用PDO执行基于另一个查询结果的查询的函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PDO执行基于另一个查询结果的查询的函数相关的知识,希望对你有一定的参考价值。

我目前正在使用PDO在mysql表上进行选择,我打印结果,这在终端中是正确的。

我正在尝试对其应用'while'循环,从odbc数据库中选择记录,其中第一个查询中的order_id等于第二个查询中的invnoc。我认为我的问题是如何调用order_id并在DB2部分中执行语句。

如果我运行这个:

$ordStatSql = 'SELECT order_id, order_status, is_placement, date_updated 
            FROM order_status';
try{
$ordStat = $MysqlConn->prepare($ordStatSql);
$result = $ordStat->execute();
}
 catch(PDOException $ex)
{
  echo "QUERY FAILED!: " .$ex->getMessage();
 }

while($row = $ordStat->fetch(PDO::FETCH_ASSOC))

{
    echo $row['order_id'] . $row['order_status'] . $row['is_placement'] . $row['date_updated'] . "\n";

}

它运行正常,没有错误,并打印我预期的每一行。

但完整的脚本:

 $ordStatSql = 'SELECT order_id, order_status, is_placement, date_updated 
            FROM order_status';
try{
$ordStat = $MysqlConn->prepare($ordStatSql);
$result = $ordStat->execute();
}
 catch(PDOException $ex)
{
  echo "QUERY FAILED!: " .$ex->getMessage();
 }

while($row = $ordStat->fetch(PDO::FETCH_ASSOC))

{
    echo $row['order_id'] . $row['order_status'] . $row['is_placement'] . $row['date_updated'] . "\n";

    $detailStatCheck = '
        SELECT 
             invnoc as INVOICE,
             fstatc as STATUS,
             cstnoc AS DEALER,
             framec AS FRAME,
             covr1c AS COVER,
             colr1c AS COLOR ,
             extd2d AS SHIPDATE,
             orqtyc AS QUANTITY
        FROM GPORPCFL
        WHERE invnoc IN ?
        ORDER BY invnoc asc 
    ';

    try{
    $detailCheck = $DB2conn->prepare($detailStatCheck);
    $detailRslt = $detailCheck->execute(['order_id']);
    $count2 = $detailCheck->rowcount();
    }
    catch(PDOException $ex)
    {
        echo "QUERY FAILED!: " .$ex->getMessage();
    }
}
echo "Matches:" . $count2

它打印相同的order_id数字,显然需要更长时间,但匹配显示-1。我知道它正在拉动匹配,因为我手动运行并匹配每条记录。我想知道我是否错误地循环或它归结为PDO错误。

任何帮助是极大的赞赏。

答案

首先,WHERE invnoc IN ?应该是= ?IN用于匹配列表中的值,而不是单个值。

其次,您需要提供execute()调用行中的值:

$detailRslt = $detailCheck->execute($row['order_id']);

第三,使用ORDER BY invnoc毫无意义,因为你只是匹配单个invnoc值。

第四,每次循环都会覆盖$count2变量。你应该在循环之前将它初始化为0,然后递增它,这样你得到总数:

$count2 += $detailCheck->rowCount();

您也不需要每次循环准备查询。查询不会更改,因此您可以在循环之前准备一次,并在循环中执行它。

另一种选择是将所有order_id值收集到一个数组中,并准备一个与IN同时匹配所有这些值的查询。

$order_ids = [];
while ($row = $ordStat->fetch(PDO::FETCH_ASSOC)) {
    $order_ids[] = $row['order_id'];
}
if (count($order_ids) > 0) {
    $placeholders = implode(',', array_fill(0, count($order_ids), '?'));
    $detailStatCheck = "
        SELECT 
             invnoc as INVOICE,
             fstatc as STATUS,
             cstnoc AS DEALER,
             framec AS FRAME,
             covr1c AS COVER,
             colr1c AS COLOR ,
             extd2d AS SHIPDATE,
             orqtyc AS QUANTITY
        FROM GPORPCFL
        WHERE invnoc IN ($placeholders)
        ORDER BY invnoc asc 
    ";
    try {
        $detailCheck = $DB2conn->prepare($detailStatCheck);
        $detailRslt = $detailCheck->execute($order_ids);
        $count2 = $detailCheck->rowCount();
        echo "Matches: $count2";
    } catch(PDOException $ex) {
        echo "QUERY FAILED!: " .$ex->getMessage();
    }
}
另一答案

您的查询工作正常(除了其他答案/评论所说的)。您的问题实际上是在ODBC数据库上的rowCount()查询中使用SELECT。来自the manual

使用odbc_num_rows()来确定SELECT之后可用的行数将返回-1并包含许多驱动程序。

因此,如果您需要计数,则需要选择COUNT(*)作为字段,然后查看值:

while($row = $ordStat->fetch(PDO::FETCH_ASSOC))
{
    echo $row['order_id'] . $row['order_status'] . $row['is_placement'] . $row['date_updated'] . "\n";

    $detailStatCheck = '
        SELECT 
            COUNT(*)
        FROM GPORPCFL
        WHERE invnoc = ?
    ';

    try {
        $detailCheck = $DB2conn->prepare($detailStatCheck);
        $detailRslt = $detailCheck->execute(['order_id']);
        $count2 = $detailCheck->fetch()[0]; // <---- correct count
    }
        catch(PDOException $ex)
    {
        echo "QUERY FAILED!: " .$ex->getMessage();
    }
}

以上是关于使用PDO执行基于另一个查询结果的查询的函数的主要内容,如果未能解决你的问题,请参考以下文章

PDO 准备和执行查询总是返回错误

AWS Redshift SQL 使用查询结果执行另一个查询

PDO多种方式取得查询结果

PHP中的PDO操作学习查询结构集

PHP中的PDO操作学习查询结构集

PDO 准备状态与手动查询的结果不同