2012-02-17 19 views
1

に私はこのような配列があります:私はTABLE_SERVICEでそれらのサービスを挿入したいDBに存在しない場合は挿入し、削除しない場合は、アレイ

$services = array(
       array("id" => "1", "desc" => "desc 1"), 
       array("id" => "2", "desc" => "desc 2"), 
       ...... 
      ); 

を。 TABLE_SERVICEに存在していればの各サービスが挿入され、TABLE_SERVICEに存在し、$servicesの配列に存在しない場合は削除されます。

私はちょうどTABLE_SERVICE内のすべてのレコードを削除してから、すべての$services要素、 を挿入しますが、私はしばしばTABLE_SERVICE$servicesの両方のデータの大規模なセットを持っているので、それがパフォーマンスの問題となることができました。

これを行う効率的な方法はありますか?

ありがとうございました。それは私だった場合

答えて

1

私は$servicesオーバー収集IDS繰り返すだろう:配列を反復処理し、PHPのjoinとその後の選択NOT IN

"DELETE FROM TABLE_SERVICE WHERE id NOT IN (" . join($ids,',') . ")" 

を使用して次に

$ids = array(); 
foreach($services as $service) 
{ 
    $ids[] = $service['id']; 
} 

を再び挿入します/更新を使用して更新する。ON DUPLICATE KEY

"INSERT INTO TABLE_SERVICE (id,desc) VALUES (?,?) ON DUPLICATE KEY UPDATE desc = ?" 

oracleにはON DUPLICATE KEYthis stackoverflow questionがありません。

+0

残念ながら、Oracleは重複しないキーをサポートしていません。それはMySqlの構文です – winkbrace

0

私の答えは、実際にこれを行う効率的な方法がないということです。 私はマージについて考えましたが、効率的であるためには、最初に一時テーブルに挿入する方が良いでしょう。次に、table_serviceを切り捨てて、$ service配列からもう一度入力してください。 Kristofferのアンワーカーが機能する場合でも、切り捨て挿入よりも遅い可能性があります。

これは私のPHPメソッドです。多くのレコードをすばやく挿入します: これは、挿入文が各挿入の代わりに1回だけ解析されるため、速度が大幅に向上するという利点があります。場合によっては100倍程度になります。

$connection = oci_connect(<YOUR CONNECTION>); 
$sql = insert into table_service (id, var) values (:id, :var); // desc is a reserved word, cannot be a column name 
$parsed = oci_parse($connection, $sql); 
$binds = array(':id', ':var'); 
$sizes = array(6, 20); 
$data = $services; 
$errors = execute_multiple($binds, $sizes, $data); 
if ($errors > 0) 
    // log or show 
else 
    // feedback: full succes! 

function execute_multiple($binds, $sizes, $data, $commit = true) 
{ 
    $errorCount = 0; 

    // first determine all binds once 
    foreach ($binds as $i => $bind) 
    { 
     // ${trim($bind, ':')} example: :some_id -> $some_id 
     oci_bind_by_name($parsed, $bind, ${trim($bind, ':')}, $sizes[$i]); 
    } 

    // Then loop over all rows and give the variables the new value for that row 
    // This is because the variables remain binded! 
    for ($row=0; $row<count($data); $row++) 
    { 
     foreach ($binds as $i => $bind) 
     { 
      $value = array_key_exists($i, $data[$row]) ? substr($data[$row][$i], 0, $sizes[$i]) : null; 
      ${trim($bind, ':')} = trim($value); 
     } 

     if (! @oci_execute($this->parsed, OCI_DEFAULT)) // don't auto commit 
      $errorCount++; 
    } 

    if ($commit) 
     oci_commit($connection); 

    return $errorCount; 
} 
関連する問題