使用 PDO 和循环插入多个值

Inserting Multiple Values with PDO and a Loop

给你一些背景知识,流程是:连接到第 3 方 API,提取存储为 json 的数据,转换为 php 并使用下面的数据代码。

我最初找到了 this work,但无法弄清楚如何修改它以满足我的需要。也许你们中的一个人能更好地理解它?

我在这里做了三件事。首先检查房屋的ID + last_update 戳以确定我的数据库中需要更新哪些房屋。如果它们存在但细节已更改,则删除当前数据并将其存储在准备插入的变量中。如果数据不存在,则插入它。

注意事项:脚本执行时间太长,我必须设置 set_time_limit(0);我意识到这是不好的做法,但我需要强制脚本完成。

考虑到我有 40 多个不同的手动输入的准备好的语句,我已经减少了很多代码:

我已经使用屏幕截图确定了预期的输出,因此请忽略此时的任何左括号,因为主要问题是将代码优化为更动态的方法并使其更快。

<?php 


$update = '';
$add = '';

if (!empty($houses)) {
foreach($houses as $travel_Prop) {

    $Prop = $travel_Prop['data'][0]; // Need to check this!

    if ($Prop['id'] > '0') { // Ignore empty arrays

        $sql= "SELECT * FROM travel_a_property WHERE travel_prop_id = :travel_prop_id";
        $stmt = $extDb->prepare("$sql");
        $stmt->bindParam(':travel_prop_id', $Prop['id'], PDO::PARAM_INT);
        $stmt->execute();
        $Result = $stmt->fetchAll(PDO::FETCH_ASSOC);
        if (!empty($Result)) {
            $travel_last_update = $Prop['last_update'];
            $local_last_update = $Result[0]['last_update'];

            if ($travel_last_update > $local_last_update) {
                $update[] = $Prop;
                echo 'Property ID: ' .$Prop['id'] .' Property modified: Updating Records.<br>';
            } else {
                echo 'Property ID: ' .$Prop['id'] .' Property details: Up to Date.<br>';
            }

        } else {
            $add[] = $Prop;
            echo 'Property ID: ' .$Prop['id'] .' Property Created: Adding to Records.';
        }
    }
}

注意:代码将在屏幕截图输出后继续

    # UPDATE
if (!empty($update)) {
//print_r($update);
foreach ($update as $PropUpdate) {

    // Get all_prop_id
    $sql= "SELECT * FROM travel_a_property WHERE travel_prop_id = :travel_prop_id";
    $stmt = $extDb->prepare("$sql");
    $stmt->bindParam(':travel_prop_id', $PropUpdate['id'], PDO::PARAM_INT);
    $stmt->execute();
    //$Result = $stmt->fetchAll(PDO::FETCH_ASSOC);
    $obj = $stmt->fetchObject();
    //echo $obj->filmName;

    $all_prop_id = $obj->all_prop_id;
    echo $all_prop_id;


    // Update master db table a_property
    $sql = "UPDATE travel_a_property SET last_update = :last_update 
    HERE all_prop_id = :all_prop_id";
    $stmt = $extDb->prepare($sql);
    $stmt->bindParam(':last_update', $PropUpdate['last_update'], PDO::PARAM_STR);
    $stmt->bindParam(':all_prop_id', $all_prop_id, PDO::PARAM_INT);
    $stmt->execute();

    echo '<br>Prop Updated - all_prop_id : ' .$all_prop_id .'<br>';


    # DELETe & INSERT

    $sql = "DELETE FROM ot_b_address WHERE glob_prop_id = :glob_prop_id";
    $stmt = $extDb->prepare($sql);
    $stmt->bindParam(':glob_prop_id', $glob_prop_id, PDO::PARAM_INT);
    $stmt->execute();

    $sql = "INSERT INTO ot_b_address(glob_prop_id, address1, address2, city, state, zip_code, 
    country, latitude, longitude) VALUES ( :glob_prop_id, :address1, :address2, :city, :state, 
    :zip_code, :country, :latitude, :longitude)";

    $stmt = $extDb->prepare($sql);

    $stmt->bindParam(':glob_prop_id', $glob_prop_id, PDO::PARAM_INT);
    $stmt->bindParam(':address1', $PropUpdate['address']['address1'], PDO::PARAM_STR);
    $stmt->bindParam(':address2', $PropUpdate['address']['address2'], PDO::PARAM_STR);
    $stmt->bindParam(':city', $PropUpdate['address']['city'], PDO::PARAM_STR);
    $stmt->bindParam(':state', $PropUpdate['address']['state'], PDO::PARAM_STR);
    $stmt->bindParam(':zip_code', $PropUpdate['address']['zip_code'], PDO::PARAM_STR);
    $stmt->bindParam(':country', $PropUpdate['address']['country'], PDO::PARAM_STR);
    $stmt->bindParam(':city', $PropUpdate['address']['city'], PDO::PARAM_STR);
    // use PARAM_STR although a number
    $stmt->bindParam(':latitude', $PropUpdate['address']['latitude'], PDO::PARAM_STR);
    $stmt->bindParam(':longitude', $PropUpdate['address']['longitude'], PDO::PARAM_STR);

    $stmt->execute();

    echo 'Address Updated <br>';



    $sql = "DELETE FROM travel_d_urls WHERE all_prop_id = :all_prop_id";
    $stmt = $extDb->prepare($sql);
    $stmt->bindParam(':all_prop_id', $all_prop_id, PDO::PARAM_INT);
    $stmt->execute();

    if (!empty($PropUpdate['urls'])) {
        foreach($PropUpdate['urls'] as $row => $Url) {
            $sql = "INSERT INTO travel_d_urls(all_prop_id, type, url) 
            VALUES ( :all_prop_id, :type, :url)";
            $stmt = $extDb->prepare($sql);

            $stmt->bindParam(':all_prop_id', $all_prop_id, PDO::PARAM_INT);
            $stmt->bindParam(':type', $Url['type'], PDO::PARAM_STR);
            $stmt->bindParam(':url', $Url['url'], PDO::PARAM_STR);
            $stmt->execute();

            echo 'URL '.$row .' Updated <br>';
        }
    }  
}
} else {
echo 'no rates to Update <br>';
}

输出几乎是一样的(不管更新了什么) URL 已添加 URL 已添加 等等

以下代码是最后一个 if 语句,它告诉脚本添加剩余的属性(如果它们不存在)。

} // 结束 foreach $update

# INSERT ONLY
if (!empty($add)) {
    foreach ($add as $PropAdd) {

        $sql = "INSERT INTO travel_a_property(travel_prop_id, last_update) 
        VALUES ( :travel_prop_id, :last_update)";

        $stmt = $extDb->prepare($sql);

        $stmt->bindParam(':travel_prop_id', $PropAdd['id'], PDO::PARAM_INT); 
        $stmt->bindParam(':last_update', $PropAdd['last_update'], PDO::PARAM_STR);

        $stmt->execute();

        $all_prop_id = $extDb->lastInsertId(); // Use this ID in all the following record inserts

        echo '<br>Prop Added - all_prop_id : ' .$all_prop_id .'<br>';

        ##########################

        $sql = "INSERT INTO travel_b_address(all_prop_id, address1, address2, city, state, zip_code, country, 
        latitude, longitude) VALUES ( :all_prop_id, :address1, :address2, :city, :state, :zip_code, :country, 
        :latitude, :longitude)";

        $stmt = $extDb->prepare($sql);

        $stmt->bindParam(':all_prop_id', $all_prop_id, PDO::PARAM_INT);
        $stmt->bindParam(':address1', $PropAdd['address']['address1'], PDO::PARAM_STR);
        $stmt->bindParam(':address2', $PropAdd['address']['address2'], PDO::PARAM_STR);
        $stmt->bindParam(':city', $PropAdd['address']['city'], PDO::PARAM_STR);
        $stmt->bindParam(':state', $PropAdd['address']['state'], PDO::PARAM_STR);
        $stmt->bindParam(':zip_code', $PropAdd['address']['zip_code'], PDO::PARAM_STR);
        $stmt->bindParam(':country', $PropAdd['address']['country'], PDO::PARAM_STR);
        // use PARAM_STR although a number
        $stmt->bindParam(':latitude', $PropAdd['address']['latitude'], PDO::PARAM_STR);
        $stmt->bindParam(':longitude', $PropAdd['address']['longitude'], PDO::PARAM_STR);

        $stmt->execute();

        echo 'Address Added <br>';
    } // end foreach
} // end !empty
$extDb = null;
}
?>

所以重申一下,这里的问题不是确定我的代码有什么问题,除了速度之外,它实际上工作正常。我想知道是否有人可以确定使此动态化的最佳方法,以避免不得不乏味地编写 40 多次代码?

如果有什么不清楚的,请告诉我。

干杯, 板凳.

您正在 foreach 循环内创建准备好的语句。尝试在它之外创建准备好的语句。准备好的语句的想法是您准备一次语句并使用不同的参数值多次执行它。这样数据库只需要编译和优化 SQL 查询一次,这比每次迭代都更有效。

if (!empty($houses)) {
    $stmt = $extDb->prepare("SELECT * FROM travel_a_property WHERE travel_prop_id = :travel_prop_id");
    //$stmt2 = ...
    foreach ($houses as $travel_Prop) {

        $prop = $travel_Prop['data'][0]; // Need to check this!

        if ($prop['id'] > '0') { // Ignore empty arrays
            if ($stmt->execute(array(':travel_prop_id' => $prop['id']))) {
                $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
                //Do something with $result
            }
        }
        //$stmt2->execute(...);
    }
}