mysql 类似merge的写法

在oracle数据库中有merge写法, 通过判定唯一键,如果存在则更新,如果不存在则插入。

pg:

在pg数据库中也有这种写法,on conflict语法,需要在ON CONFLICT后指定唯一键以此来判定是更新还是插入

 INSERT ... ON CONFLICT [ conflict_target ] conflict_action

INSERT INTO book_borrow_record ( book_id, borrow_times )
VALUES
    ( 'b0001', 1 ),
    ( 'b0002', 1 ),
    ( 'b0003', 1 )
ON CONFLICT ( book_id )
DO UPDATE
    SET borrow_times = book_borrow_record.borrow_times + 1;

mysql:

在mysql中也有类似写法,数据库版本为5.7,写法如下:

INSERT ... ON DUPLICATE KEY UPDATE

mysql在执行sql时会判断插入会不会报数据重复错误,如果会则执行更新。

insert into pay_sign_info (
    uid,user_name,
    id_card,city_code,gateway,
    sign_status,sign_date,release_date,
    sequence,sign_token,bank_card,
    bank_code,sign_mobile,create_time,
    update_time
) values (
    #{uid},#{userName},
    #{idCard},#{cityCode}, #{gateway},
    #{signStatus},#{signDate},#{releaseDate},
    #{sequence},#{signToken},#{bankCard},
    #{bankCode},#{signMobile},#{createTime},
    #{updateTime}
)  ON DUPLICATE KEY
UPDATE sign_status = #{signStatus},
    update_time = #{updateTime}
    <if test="releaseDate != null">
        ,release_date = #{releaseDate}
    </if>

同时这种写法也支持批量插入和批量更新,如下
insert into prescription_auth_info (
        medical_insurance_code,id_card_type,id_card,ec_token,patient_name,insu_admdvs,auth_rxno,epc_token,
        expirex_in,prsc_time,dept_name,vali_end_time,out_order_id,rx_trace_code,long_rx_flag,rx_file,rx_chk_biz_sn,
        rx_sign_verify_sn,dise_codg,merchant_id,patient_phone,creator,updater
        ) values
        <foreach collection="authInfoList" item="authInfo" separator=",">
            (#{authInfo.medicalInsuranceCode},
            #{authInfo.idCardType},
            #{authInfo.idCard},
            #{authInfo.ecToken},
            #{authInfo.patientName},
            #{authInfo.insuAdmdvs},
            #{authInfo.authRxno},
            #{authInfo.epcToken},
            #{authInfo.expirexIn},
            #{authInfo.prscTime},
            #{authInfo.deptName},
            #{authInfo.valiEndTime},
            #{authInfo.outOrderId},
            #{authInfo.rxTraceCode},
            #{authInfo.longRxFlag},
            #{authInfo.rxFile},
            #{authInfo.rxChkBizSn},
            #{authInfo.rxSignVerifySn},
            #{authInfo.diseCodg},
            #{authInfo.merchantId},
            #{authInfo.patientPhone},
            #{authInfo.creator},
            #{authInfo.updater})
        </foreach>
        on duplicate key update
        medical_insurance_code = values(medical_insurance_code),
        long_rx_flag = values(long_rx_flag),
        rx_file = values(rx_file),
        rx_chk_biz_sn = values(rx_chk_biz_sn),
        rx_sign_verify_sn = values(rx_sign_verify_sn),
        dise_codg = values(dise_codg),
        out_order_id = values(out_order_id),
        rx_trace_code = values(rx_trace_code),
        updater = values(updater),
        update_time =NOW()

                
<think>好的,我现在需要回答用户关于OracleMERGE INTO语句的用法和示例的问题。首先,我需要回忆MERGE INTO的基本概念。MERGE INTO用于根据条件合并两个表的数据,可以同时处理更新和插入操作,这在数据仓库中很常见。 接下来,用户可能需要语法结构。我记得MERGE INTO的基本结构包括目标表、USING子句指定源数据,ON条件判断匹配,然后WHEN MATCHED和WHEN NOT MATCHED分别处理更新和插入。需要确认语法是否正确,比如是否需要分号,各部分的顺序。 然后,用户需要示例。我应该构造一个简单的例子,比如将员工奖金表的数据合并到总表中。假设有源表bonus和目标表employee,当员工ID匹配时更新奖金,不匹配时插入新记录。要写出具体的SQL语句,包括字段名和条件。 还要注意Oracle版本的区别,比如10g之后支持DELETE和条件操作。但用户可能只需要基础示例,所以先提供基本用法,再提到高级功能。 用户提供的引用中提到MySQL的替代方案是INSERT ... ON DUPLICATE KEY UPDATE,这可能对迁移有帮助,但用户的问题集中在Oracle,所以暂时不深入。 需要检查引用内容,引用1到4提到了语法、注意事项、迁移改造等,但用户需要的是用法和示例,所以重点在语法和示例部分,适当引用参考资料。 另外,用户可能关心性能、常见错误或最佳实践,但问题明确要求用法和示例,所以保持答案简洁,最后生成相关问题引导进一步学习。 最后,确保使用正确的中文术语,LaTeX格式的行内公式,如$table_name$,独立公式用$$...$$,但这里可能用不上。检查是否有语法错误,比如MERGE INTO的正确写法,字段列表的括号是否正确。</think>### Oracle MERGE INTO 语法及使用示例 #### 1. 基本语法 Oracle 的 `MERGE INTO` 语句用于将源表(或子查询)与目标表进行数据合并,根据匹配条件执行更新或插入操作。语法结构如下: ```sql MERGE INTO 目标表 别名 USING (源表/视图/子查询) 别名 ON (匹配条件) WHEN MATCHED THEN UPDATE SET 列1=值1, 列2=值2... [WHERE 条件] -- 10g及以上支持 [DELETE WHERE 条件] -- 10g及以上支持 WHEN NOT MATCHED THEN INSERT (列1, 列2...) VALUES (值1, 值2...) [WHERE 条件]; -- 10g及以上支持 ``` #### 2. 核心功能 - **更新匹配数据**:当 `ON` 条件满足时,执行 `UPDATE` 操作[^3] - **插入不匹配数据**:当 `ON` 条件不满足时,执行 `INSERT` 操作[^3] - **条件过滤**(10g+):可为 `UPDATE/INSERT` 添加额外条件[^3] - **删除操作**(10g+):可在匹配后通过 `DELETE WHERE` 删除数据[^3] #### 3. 使用示例 **场景**:将奖金表 `bonus` 的数据合并到员工表 `employees` 中,匹配时更新工资,不匹配时插入新记录。 ```sql MERGE INTO employees e USING ( SELECT employee_id, salary, bonus FROM bonus WHERE year = 2023 ) b ON (e.employee_id = b.employee_id) WHEN MATCHED THEN UPDATE SET e.salary = e.salary + b.bonus WHERE b.bonus > 1000 -- 仅当奖金超过1000时更新 WHEN NOT MATCHED THEN INSERT (employee_id, salary, hire_date) VALUES (b.employee_id, b.salary, SYSDATE); ``` #### 4. 注意事项 1. **锁机制**:执行时会锁定目标表,高并发场景需注意性能[^1] 2. **条件准确性**:`ON` 条件需唯一,否则可能重复操作[^1] 3. **日志与回滚**:建议开启日志以便故障恢复[^1] 4. **替代方案**:迁移到 MySQL 可使用 `INSERT ... ON DUPLICATE KEY UPDATE`[^4] #### 5. 版本差异 - **Oracle 9i/10g前**:仅支持基础更新/插入[^3] - **Oracle 10g+**:支持条件操作和删除[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值