PDO 因记录过多、缓冲查询而失败

2024-01-03

这个脚本昨天运行良好,但是今天,由于我最初选择的表中现在有大约 150,000 条记录,所以它失败了,说我正在从 null() 获取。据我所知,这是因为我的记录太多了。

因此,我最终通过向初始查询(1000)添加限制和这一行来纠正它:

$MysqlConn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

在我运行脚本的前 15 次左右,这有效,但现在失败了,并且没有进行任何插入。我收到一个错误,因为 buffered_query 为 false,表示它可以在另一个查询正在进行时运行缓冲查询。

我以前从未使用过这个,更不用说遇到这个错误了。我确信我的代码可以为此进行优化(在使用 PDO 方面我也很陌生)。

也许有人可以提供一些见解:

$MysqlConn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$MysqlConn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);



/*Delete records that were made placements more than 5 days ago*/
$deleteOld = '
        DELETE 
        FROM Order_status 
        WHERE date_updated < current_date() - INTERVAL 5 DAY';
try{
$delete = $MysqlConn->prepare($deleteOld);
$result = $delete->execute();
$count = $delete->rowcount();
echo "Records Deleted: " . $count . "\n";
}
catch(PDOException $ex)
{
    echo "QUERY FAILED!: " .$ex->getMessage();
}

/*Placement process for orders already marked as Shipped*/
//PDO statement to select from order_status
$ordStatSql = 'SELECT order_id, order_status, is_placement, date_updated 
                FROM order_status
                WHERE order_status = "S"
                AND date_updated IS NULL
                order by order_id desc
                LIMIT 1000';
try{
$ordStat = $MysqlConn->prepare($ordStatSql);
$result = $ordStat->execute();
}
catch(PDOException $ex)
{
    echo "QUERY FAILED!: " .$ex->getMessage();
}

$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)
    ";

    try {
        $detailCheck = $DB2conn->prepare($detailStatCheck);
        $detailRslt = $detailCheck->execute($order_ids);
        $count2 = $detailCheck->fetch();
        print_r($order_ids);
        print_r($count2);
    } catch(PDOException $ex) {
        echo "QUERY FAILED!: " .$ex->getMessage();
    }

    //Create prepared INSERT statement
    $insertPlacement = "
        INSERT ignore INTO placements_new (sku_id, group_id, dealer_id, start_date, expire_date, locations, order_num)
        SELECT 
            id, 
            sku_group_id, 
            :DEALER, 
            DATE_ADD(DATE_FORMAT(CONVERT(:SHIPDATE, CHAR(20)), '%Y-%m-%d'),INTERVAL 7 DAY) as start_date,
            DATE_ADD(DATE_FORMAT(CONVERT(:SHIPDATE, CHAR(20)), '%Y-%m-%d'),INTERVAL 127 DAY) as expire_date, 
            :QUANTITY,
            :INVOICE  
        FROM skus s  
        WHERE  s.frame=:FRAME AND s.cover1=:COVER AND s.color1=:COLOR
    ";

    //create update statement for necessary constraints
    $updatePlacement = "
        UPDATE placements_new 
        SET expire_date = DATE_ADD(DATE_FORMAT(CONVERT(current_date(), CHAR(20)), '%Y-%m-%d'),INTERVAL 127 DAY)
    ";

    //perpare query to check for existing records that are expired
    $expiredCheck = "
        SELECT 
            sku_id,
            dealer_id,
            expire_date
        FROM placements_new p
            INNER JOIN skus s
                ON p.sku_id = s.id
        WHERE p.dealer_id = :DEALER
            AND   s.frame = :FRAME
            AND   s.cover1 = :COVER
            AND   s.color1 = :COLOR
            AND   p.order_num = :INVOICE
            AND   p.expire_date <= current_date()
    ";

    //perpare query to check for existing records that are expired
    $validCheck = "
        SELECT 
            sku_id,
            dealer_id,
            expire_date
        FROM placements_new p
            INNER JOIN skus s
                ON p.sku_id = s.id
        WHERE p.dealer_id = :DEALER
            AND   s.frame = :FRAME
            AND   s.cover1 = :COVER
            AND   s.color1 = :COLOR
            AND   p.order_num = :INVOICE
            AND   p.expire_date > current_date()
    ";

    $updateShipped = '
        UPDATE order_status S
        INNER JOIN placements_new N 
        ON S.order_id = N.order_num
        set S.date_updated = current_date();
    ';


    while ($row2 = $detailCheck->fetch(PDO::FETCH_ASSOC)) {

        $values = [
            ":DEALER" => $row2["DEALER"],
            ":SHIPDATE" => $row2["SHIPDATE"],
            ":QUANTITY" => $row2["QUANTITY"],
            ":INVOICE" => $row2["INVOICE"],
            ":FRAME" => $row2["FRAME"],
            ":COVER" => $row2["COVER"],
            ":COLOR" => $row2["COLOR"],
        ];

        $values2 = [
            ":DEALER" => $row2["DEALER"],
            ":FRAME" => $row2["FRAME"],
            ":COVER" => $row2["COVER"],
            ":COLOR" => $row2["COLOR"],
            ":INVOICE" => $row2["INVOICE"],

        ];

        try{
            //Array will contain records that are expired
            $checkExisting = $MysqlConn->prepare($expiredCheck);
            $existingRslt = $checkExisting->execute($values2);
            $count3 = $checkExisting->fetch(PDO::FETCH_ASSOC);

            //Array will contain records that are valid
            $checkExistingValid = $MysqlConn->prepare($validCheck);
            $existingVldRslt = $checkExistingValid->execute($values2);
            $count4 = $checkExistingValid->fetch(PDO::FETCH_ASSOC);

            //print_r($count3);

        }catch(PDOException $ex){
                echo "QUERY FAILED!!!: " . $ex->getMessage();
        }



            // IF records do not exist, or records exist and today is after expiration date
            if(empty($count3) && empty($count4)){
                for($i=0; $i<$row2["QUANTITY"]; $i++) {  
                    try{
                        $insert = $MysqlConn->prepare($insertPlacement);
                        $insertRslt = $insert->execute($values);
                    }catch(PDOException $ex){
                        echo "QUERY FAILED!!!: " . $ex->getMessage();
                    }

                }
            }elseif(!empty($count3)){
                for($i=0; $i<$row2['QUANTITY']; $i++){
                    try{
                        $insert = $MysqlConn->prepare($insertPlacement);
                        $insertRslt = $insert->execute($values);
                    }catch(PDOException $ex){
                        echo "QUERY FAILED!!!: " . $ex->getMessage();
                    }
                }
            }elseif(!empty($count4)){
                for($i=0; $i<$row2['QUANTITY']; $i++){
                    try{
                        $update = $MysqlConn->prepare($updatePlacement);
                        $updateRslt = $update->execute($values);
                    }catch(PDOException $ex){
                        echo "QUERY FAILED!!!: " . $ex->getMessage();
                    }
                }
            }else{
                die("No action taken");
            }
         }


                try{
                $updateStatus = $MysqlConn->prepare($updateShipped);
                $statUpdateRslt = $updateStatus->execute();
                $count = $updateStatus->rowcount();
                }
                catch(PDOException $ex)
                {
                    echo "QUERY FAILED!: " .$ex->getMessage();
                }
            echo "Records Updated: " . $count . "\n";


}

当您使用无缓冲查询时,这意味着您的结果集是从 MySQL 服务器流入的。因此,运行(无缓冲)查询的连接一直处于繁忙状态,直到您读取查询的最后一行。在你的情况下,连接是$MysqlConn.

(缓冲查询将整个结果集放入 PHP 程序的 RAM 中并释放连接。当整个结果集不适合 RAM 时,可以使用非缓冲查询)。

当您完成无缓冲查询时,应显式关闭它们。所以add a closeCursor() call http://php.net/manual/en/pdostatement.closecursor.php。像这样。

while ($row = $ordStat->fetch(PDO::FETCH_ASSOC)) {
    $order_ids[] = $row['order_id'];
}
$ordStat->closeCursor();

关闭缓冲查询也没有什么坏处。这是一个好习惯。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PDO 因记录过多、缓冲查询而失败 的相关文章

随机推荐

  • 克隆时 IE8 无法识别 Html 5 时间标签

    在这种情况下 我一直无法让 IE 识别新的时间标签 这一切在 FF 中都很有效 这是代码 var origComment articleComment first div if origComment length gt 0 var com
  • JavaScript 动态函数名

    我需要将函数的名称动态分配给关联数组的元素 这是我的尝试 但行不通 我寻求帮助的问题是在这里我尝试调用该函数 cr cmd1 x
  • 缺少函数的返回类型 - 在反应(打字稿)代码中

    在我的 App tsx 中我得到了这个 function eslint 上缺少返回类型 typescript eslint explicit function return type 在我的主类组件中 我得到了这些 方法定义中缺少可访问性修
  • Dynamics CRM 2016 本地插件 - 异常:无法加载文件或程序集“Microsoft.IdentityModel.Clients.ActiveDirectory”

    我有一个 Dynamics CRM 2016 On Prem 插件 它连接到使用 Azure AD 保护的 ASP Net Web api 端点 因此我使用图书馆Microsoft IdentityModel Clients ActiveD
  • PHP 的 MongoDB 连接器:计算分页文档数

    我正在使用MongoDB Driver Manager使用 PHP 连接到 MongoDB 驱动程序版本是1 6 14 我可以连接并进行查询 但我需要查询的文档总数才能进行分页 reg pag 20 pag GET pag mng new
  • 为什么 Tomcat 管理器使用我的 LoginModule?

    我正在运行 Tomcat 6 0 29 并创建了我自己的领域和登录模块 它们在 server xml 中定义如下
  • C 和 C++ 中枚举的用途是什么

    枚举是常量整数值的列表 可以使用它来代替使用 define 定义常量值 但除此之外 我还没有在 C 和 CPP 中发现枚举的任何实质性用途 任何人都可以让我知道枚举的确切用途是什么 最初我想如果我们创建一个枚举变量并分配一个不在枚举值中的值
  • 将对象转换为 JAXBElement

    我想实现一个返回 JAXBElement 的方法 下面是代码 XmlRootElement name history XmlAccessorType XmlAccessType FIELD public class IBHistoryInf
  • 从表单中的所有选择元素中获取所有选定的选项元素

    大家好 感谢您抽出时间回答我的问题 我有一个包含 6 个选择元素的表单 其类别为 skillLevel 我需要使用 jQuery 获取 最好是在数组中 每个选择元素的值 我怎样才能做到这一点 您可以使用map method var arr
  • HTML 钻取表:设计

    我试图找出根据标签构建 HTML 钻取表的最佳方法 它必须简单 但最重要的是它应该符合逻辑 关于如何做到这一点是否有任何首选标准 你会推荐什么 一种可能的解决方案是 colspan tbody tr td td td Summery row
  • 更改 PHP.ini 位置文件?

    我在 OSX 上使用 apache2 默认情况下php ini位置是 private etc php ini 我需要把它改成这样 Library FileMaker Server Web Publishing publishing engi
  • Delphi 2010-IDE 不断停止在 CPU 调试窗口

    我在 D2010 IDE 中不断出现 CPU 调试窗口 我注意到这出现在一些断点上 而其他一些断点则不会导致这种效果 无法解释这种情况到底何时发生或哪些断点导致这种情况 但似乎当调试器无法到达代码上的断点时 它会停止在方法的开始地址上 并且
  • 在 jar 中包含属性/配置文件是一种不好的做法吗?

    例如 MyApp 是一个 Web 应用程序 其中包含一个属性文件 server properties 该文件描述应用程序的配置数据 例如服务器名称 在开发阶段 server properties 位于其自己的 IDE 项目文件夹中 它的逻辑
  • 当终端关闭时终止 sudo python 脚本

    如何判断运行 python 脚本的终端是否已关闭 如果用户关闭终端 我想安全地结束我的 python 脚本 我可以使用处理程序捕获 SIGHUP 但当脚本作为 sudo 运行时则不行 当我使用 sudo 启动脚本并关闭终端时 python
  • 模拟内存不足警告不起作用

    我有一个UIWebView in a UIViewController 我正在尝试将此视图控制器推送到现有的UINavigationController 它有另一个视图控制器 它也有一个UIWebView在里面 推动第一个视图控制器后 我尝
  • 单击时切换 CSS3 动画

    在没有 JavaScript 的情况下 在点击时改变 CSS3 动画方向的最佳方法是什么 我最近一直在探索复选框黑客 并试图找到一种方法 只使用一组关键帧 而不是两组 一个前进 一个返回 这可能吗 或者有没有办法用一套来做到这一点 例如我有
  • 如何删除mysql数据库中的重复记录?

    使用rails或mysql查询删除mysql数据库中重复记录的最佳方法是什么 您可以通过以下方式将不同的记录复制到新表中 select distinct into NewTable from MyTable
  • 如何使用 Gradle 运行多个命名测试?

    我知道怎么说 gradle test tests mypackage MyTest 但如何指定多个呢 gradle test tests mypackage MyTest mypackage model ModelTest BasicTes
  • 了解 Qt 中的表单布局机制

    Qt具有灵活且强大的布局机制来处理桌面应用程序窗口的视图 但它是如此灵活 以至于当出现问题并需要微调时 它几乎无法被理解 而且如此强大 以至于它可以击败任何试图压倒 Qt 关于表单外观的观点的人 那么 谁能解释一下 或者提供一下Qt的定位机
  • PDO 因记录过多、缓冲查询而失败

    这个脚本昨天运行良好 但是今天 由于我最初选择的表中现在有大约 150 000 条记录 所以它失败了 说我正在从 null 获取 据我所知 这是因为我的记录太多了 因此 我最终通过向初始查询 1000 添加限制和这一行来纠正它 MysqlC