【问题标题】:Oracle SQL equivalent of MySQL bulk insertOracle SQL 等效于 MySQL 批量插入
【发布时间】:2019-08-10 22:30:57
【问题描述】:

我有一张这样的桌子:

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 SQL 通过MERGE 语句具有这种能力。但是您是在询问原始 SQL 语句,还是需要通过您的框架使用此功能?
  • 它在多个地方使用,但我只需要查看一种有效的语法,我就可以从那里获取它。我目前正在从 MySQL 迁移到 Oracle,这是一段不容易迁移的代码。谢谢!

标签: plsql yii2 oracle12c on-duplicate-key batch-insert


【解决方案1】:

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 吗?我不知道是相反的一天。

【讨论】:

  • 这很有帮助!比你。我明天会测试它并标记为已回答
  • 关于 MySQL:是的,我很不情愿地离开 MySQL。我们的 IT 部门说 Oracle 更好。个人看不出优势!!如果我有相反的证据,我会很乐意挥舞它! :-)
  • 从我对 MySQL 的有限经验来看,我认为 Oracle 的 SQL 和 PL/SQL 语法更强大,可以带来更简单的代码和性能提升。但是该软件要花费的钱。我猜你的 IT 部门没有注意价格。某天,一位会计师会与 CTO 进行一次不愉快的谈话,而你会迁移回来。但是,嘿,至少这会给你一些工作保障。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    相关资源
    最近更新 更多