使用PDO和循环插入多个值

时间:2016-12-15 12:19:27

标签: php sql dynamic pdo bindparam

为了给你一些背景知识,流程是:连接到第三方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.';
        }
    }
}

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

enter image description here

    # 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多次代码?

如果有任何不清楚的地方,请告诉我。

干杯, 台上。

1 个答案:

答案 0 :(得分:1)

您正在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(...);
    }
}