Php 如果数据库中不存在,则插入;如果数组中不存在,则删除

Php 如果数据库中不存在,则插入;如果数组中不存在,则删除,php,oracle,plsql,Php,Oracle,Plsql,我有这样一个数组: $services = array( array("id" => "1", "desc" => "desc 1"), array("id" => "2", "desc" => "desc 2" ), ...... ); 我想在表\u SERVICE中插入这些服务。 如果每个服务不存在于TABLE\u service中,则将其插入;如果每

我有这样一个数组:

$services = array(
               array("id" => "1", "desc" => "desc 1"), 
               array("id" => "2", "desc" => "desc 2" ),
               ......
            );
我想在
表\u SERVICE
中插入这些服务。 如果每个服务不存在于
TABLE\u service
中,则将其插入;如果每个服务存在于
TABLE\u service
中,但不存在于
$services
数组中,则将其删除

我可以删除
表服务中的所有记录,然后插入所有
$services
元素, 但这可能会影响性能,因为我经常在
表服务
$services
中都有大量数据

那么有没有一种有效的方法来做到这一点呢


谢谢。

如果是我,我会反复使用
$services
收集ID:

$ids = array();
foreach($services as $service)
{
    $ids[] = $service['id'];
}
然后使用PHP和select

之后,再次迭代数组,使用


由于oracle没有重复键上的
可能会帮助您完成最后一部分。

我的答案是,没有真正有效的方法来完成这一点。 我曾考虑过合并,但为了提高效率,最好还是先将其插入到临时表中。然后,您还可以截断表_服务,然后从$service数组中再次填充它。 即使Kristofer的anwser可以工作,它也可能比截断插入慢

这是我快速插入大量记录的php方法: 这样做的好处是,您的insert语句将只被解析一次,而不是针对每个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;
}
$connection=oci_connect();
$sql=插入表_服务(id,var)值(:id,:var);//desc是保留字,不能是列名
$parsed=oci_parse($connection,$sql);
$binds=array(':id',':var');
$sizes=阵列(6,20);
$data=$services;
$errors=execute\u multiple($binds,$size,$data);
如果($errors>0)
//记录或显示
其他的
//反馈:完全成功!
函数execute\u multiple($binds,$size,$data,$commit=true)
{
$errorCount=0;
//首先确定所有绑定一次
foreach($binds为$i=>$bind)
{
//${trim($bind,:')}示例::some_id->$some_id
oci_bind_by_name($parsed,$bind,${trim($bind,,:')},$size[$i]);
}
//然后在所有行上循环,并给变量该行的新值
//这是因为变量保持绑定状态!
对于($row=0;$row$bind)
{
$value=array\u key\u存在($i,$data[$row])?substr($data[$row][$i],0,$size[$i]):null;
${trim($bind,,:')}=trim($value);
}
如果(!@oci_execute($this->parsed,oci_DEFAULT))//不自动提交
$errorCount++;
}
如果($commit)
oci_提交(连接);
返回$errorCount;
}

不幸的是,Oracle不支持重复密钥。这是MySql语法
"INSERT INTO TABLE_SERVICE (id,desc) VALUES (?,?) ON DUPLICATE KEY UPDATE desc = ?"
$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;
}