Oracle SQL 相当于 MySQL 批量插入



>我有这样的表格:

email (primary-key) | first_contact_date | last_contact_date | due_date | status

用户可以将 excel 电子表格(从不同的应用程序(上传到表中。该 excel 包含:

email | first_contact_date | last_contact_date 

加载后,用户可以更改(更新(状态和截止日期。

但是,大约每周一次,用户将上传包含新记录和旧记录的最新 excel 电子表格。换句话说,表中已存在某些行并已处理。

因此,我们无法删除现有记录。相反:

  • 如果记录是新记录,请插入
  • 如果表中已经存在记录(即电子邮件存在(,那么我们需要更新last_contact_date

Excel 电子表格可以包含 1,000 到 50,000 行。

将记录插入 Oracle 的最有效方法是什么?在mySQL中,我只是使用带有"重复更新"的批量插入,但Oracle没有此功能。

最好的方法是什么?

任何帮助表示赞赏。

Oracle的MERGE语法有点棘手。 但值得在这里使用,因为它比使用UPDATEINSERT语句的某种组合更快。

--Create table and initial data.
create table contacts
(
email varchar2(100) primary key,
first_contact_date date,
last_contact_date date,
due_date date,
status varchar2(100)
);
insert into contacts values('a@a.com', sysdate, sysdate, sysdate, 'open');
insert into contacts values('b@b.com', sysdate, sysdate, sysdate, 'open');
commit;

--Merge (upsert) new rows into the table.
merge into contacts
using
(
select 'b@b.com' email, date '2000-01-01' first_contact_date, date '2000-01-01' last_contact_date from dual union all
select 'c@c.com' email, date '2000-01-01' first_contact_date, date '2000-01-01' last_contact_date from dual
) new_contacts
on (contacts.email = new_contacts.email)
when matched then update set
contacts.first_contact_date = new_contacts.first_contact_date,
contacts.last_contact_date = new_contacts.last_contact_date
when not matched then insert
values(new_contacts.email, new_contacts.first_contact_date, new_contacts.last_contact_date, null, null);

顺便说一句,你说你要MySQL迁移到Oracle吗? 我不知道这是相反的一天。

Yii 2 有upsert()它以你想要的方式工作,但只支持插入/更新一条记录。因此,对于 50k 记录,您需要 50k 更新插入查询 - 绝对不是最有效的解决方案,但至少语法很简单,它可以保护您免受竞争条件的影响(操作是原子的(:

Yii::$app->db->createCommand()
->upsert($tableName, $row, ['last_contact_date' => $row['last_contact_date'])
->execute();