如果DB中不存在则插入,如果不在数组中则删除

时间:2012-02-17 09:11:47

标签: php oracle plsql

我有一个这样的数组:

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

我想在TABLE_SERVICE中插入这些服务。 如果TABLE_SERVICE中不存在,则会插入每个服务,如果TABLE_SERVICE中存在$services但不存在,则将其删除。

我可以删除TABLE_SERVICE中的所有记录,然后插入所有$services元素, 但这可能是性能问题,因为我经常在TABLE_SERVICE$services都有大量数据。

那么有效的方法吗?

感谢。

2 个答案:

答案 0 :(得分:1)

如果是我,我会迭代$services收集ID:

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

然后使用PHP的join和选择NOT IN

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

之后,再次迭代数组以使用ON DUPLICATE KEY

插入/更新
"INSERT INTO TABLE_SERVICE (id,desc) VALUES (?,?) ON DUPLICATE KEY UPDATE desc = ?"

由于oracle没有ON DUPLICATE KEY this stackoverflow question可能会帮助你完成最后一部分。

答案 1 :(得分:0)

我的回答是,没有一种有效的方法可以做到这一点。 我考虑过合并,但为了提高效率,首先将其插入临时表中仍然会更好。然后你也可以截断table_service,然后从$ service数组中再次填充它。 即使Kristoffer的anwser可以工作,它仍然可能比截断插入更慢。

这是我快速插入大量记录的php方法: 这样做的好处是,对于每个插入,您的insert语句只会被解析一次,这将大大提高速度。有时候是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;
}