在 SELECT 查询之前插入未完成

时间:2021-07-12 14:47:21

标签: php mysql mysqli

我有一个 PHP 脚本,它被分成两个单独的 PHP 脚本(因为它们每个都有一个目的并且很长)。为简单起见,我们将它们称为 1.php 和 2.php。

Script 1.php 对网站进行 API 调用,将有效负载传递给函数。一旦截断新记录并将其插入表中,它就会包含第二个脚本。这就是问题开始的地方。似乎当我查询 marketPlace 表时,它返回一个空数组,但是如果我在包含 2.php 之前插入一个 sleep(1) ,它就可以工作!我只能总结一下,在调用下一个查询之前,1.php 中的截断和插入查询以某种方式尚未完成? (我以前从未遇到过这种情况!)。

只有一个数据库连接,由1.php中包含的数据库类定义:

class Database
{

    // This class allows us to access the database from any function with ease
    // Just call it with Database::$conn

    /** TRUE if static variables have been initialized. FALSE otherwise
    */
    private static $init = FALSE;
    /** The mysqli connection object
    */
    public static $conn;
    /** initializes the static class variables. Only runs initialization once.
    * does not return anything.
    */
    public static function initialize()
    {


        Global $servername;
        Global $username;
        Global $password;
        Global $dbname;

        try {

            if (self::$init===TRUE)return;
            self::$init = TRUE;
            self::$conn = new mysqli($servername, $username, $password, $dbname);

        }

        catch (exception $e) {
            date('Y-m-d H:i:s',time()) . " Cant' connect to MySQL Database - re-trying" . PHP_EOL;
        }
    }

    public static function checkDB()
    {

        if (!mysqli_ping(self::$conn)) {
            self::$init = FALSE;
            self::initialize();
        }

    }

}

截断并插入市场的功能是:

function processMarketplace($marketData) {

    // Decode to JSON
    $outputj = json_decode($marketData, true);
    $marketplaceCounter = 0;

    // Check for success
    if (($outputj['success']==true) && (!stristr($marketData, "error"))) {

        // Create the blank multiple sql statement
        $sql = "TRUNCATE marketplace;";  // Clears down the current marketPlace table ready for new INSERTS

        //Loop through each multicall
        foreach ($outputj['multiCall'] as $orderBook) {
            foreach ($orderBook['marketplace'] as $orderLine) {

                $type = $orderLine['type'];
                $price = $orderLine['amountCurrency'];

                // Add new SQL record (This ignores any duplicate values)
                $sql .="INSERT IGNORE INTO marketplace (type, price) VALUES ('" . $type . "'," . $price . ");";

            }

            $marketplaceCounter++;

        }

        // Now run all the SQL's to update database table
        if (strlen($sql) > 0) {
            if (Database::$conn->multi_query($sql) === TRUE) {
                 echo mysqli_error(Database::$conn);
                //echo "New records created successfully";
            } else {
                echo mysqli_error(Database::$conn);
                echo "Error: " . $sql . "<br>" . Database::$conn->error;
            }
        }

        echo date('Y-m-d H:i:s',time()) . " == Marketplace Orderbook retreived == <BR><BR>" . PHP_EOL;

    } else {

        echo date('Y-m-d H:i:s',time()) . " Failed to get Marketplace data. Output was: " . $marketData . "<BR>" . PHP_EOL;
        die();
    }

}

我已经追了几个小时,我真的不明白为什么在调用 sleep(1) 函数后添加 processMarketplace() 延迟会有帮助。我还尝试将 1.php 和 2.php 合并为一个脚本,这会产生相同的结果。 2.php 只是执行 SELECT * FROM marketPlace 查询,除非我有 sleep(1),否则返回 NULL。

我是否遗漏了一些简单的东西,还是我真的很糟糕?

我应该补充一点,我正在使用 InnoDB 表。

在 1.php 中是这样调用的:

$marketData = getData($user,$api); // Get Marketplace Data
processMarketplace($marketData); // Process marketplace data
sleep(1); // Bizzare sleep needed for the select statement that follows in 2.php to return non-null
include "2.php"; // Include 2nd script to do some select statements on marketPlace table

2.php 包含以下调用:

$typeArray = array('1','2','3');
foreach ($typeArray as $type) {

    initialPopulate($type);

}

function initialPopulate($type) {

// Reset supplementary prices
mysqli_query(Database::$conn, "UPDATE marketPlace SET price_curr = '999999' WHERE type='" . $type . "'");
echo mysqli_error(Database::$conn);

// Get marketplace data <--- This is the one that is strangely returning Null (after the first loop) unless I place the sleep(1) before including 1.php
$query = "SELECT * FROM marketPlace WHERE type='" . $type . "'";
$result = mysqli_query(Database::$conn, $query);echo mysqli_error(Database::$conn);
$resultNumRows = mysqli_num_rows($result);echo mysqli_error(Database::$conn);

// Create array from mysql data
$rows = array();
while($r = mysqli_fetch_assoc($result)) {
    $rows[] = $r;
}

// Get information from the offertypes table
$query2 = "SELECT offerID FROM queryTypes WHERE type='" . $type . "'";
$result2 = mysqli_query(Database::$conn, $query2);echo mysqli_error(Database::$conn);

// Create array from mysql data
$rows2 = array();
while($r2 = mysqli_fetch_row($result2)) {
    $rows2[] = $r2;
}

// Loop through marketplace data and apply data from the offertypes table
$sql1 = "";     // Create a blank SQL array that we will use to update the database
$i = 0;
foreach ($rows as $row) {

    $sql1 .= "UPDATE marketPlace SET enrichmentType = " . $rows2[$i][0] . " WHERE type='" . $type . "';";
    $i++;
}

// Now run all the SQL's to update database table
if (strlen($sql1) > 0) {
    if (Database::$conn->multi_query($sql1) === TRUE) {
         echo mysqli_error(Database::$conn);
        //echo "New records created successfully";
    } else {
        echo mysqli_error(Database::$conn);
        echo "Error: " . $sql1 . "<br>" . Database::$conn->error;
    }
}

}

1 个答案:

答案 0 :(得分:1)

您正在使用 mysqli:multi_query。 与 query 不同,multi_query 不会立即检索结果。检索结果必须使用 mysqli::use_result

文档中的示例:



/* execute multi query */
if ($mysqli->multi_query($query)) {
    do {
        /* store first result set */
        if ($result = $mysqli->use_result()) {
            while ($row = $result->fetch_row()) {
                printf("%s\n", $row[0]);
            }
            $result->close();
        }
        /* print divider */
        if ($mysqli->more_results()) {
            printf("-----------------\n");
        }
    } while ($mysqli->next_result());
}

您不需要打印结果,但如果您不检索它们,则不能保证 INSERT 已完成。

use_result 的文档中注意 https://www.php.net/manual/en/mysqli.use-result.php

说明

<块引用>

"必须调用此函数或 mysqli_store_result() 函数 在可以检索查询结果之前,以及其中一个 必须调用以阻止对该数据库连接的下一个查询 失败。”

由于未调用 store_result 或 use_result,您将获得不可预测的结果。

相关问题