GVKun编程网logo

oracle sql: update if exists else insert

18

本文将带您了解关于oraclesql:updateifexistselseinsert的新内容,另外,我们还将为您提供关于c#–TSQL:带INSERTINTOSELECTFROM的UPDATE、CQ

本文将带您了解关于oracle sql: update if exists else insert的新内容,另外,我们还将为您提供关于c# – TSQL:带INSERT INTO SELECT FROM的UPDATE、CQL(Cassandra)中是否有“IF EXISTS UPDATE ELSE INSERT”命令?、mybatis+sqlServer 实现insertOrUpdate、Oracle DML语句(insert,update,delete) 回滚开销估算的实用信息。

本文目录一览:

oracle sql: update if exists else insert

oracle sql: update if exists else insert

我有一个表,如果已经存在一条记录,则必须对其进行修改,否则必须插入一条新记录。Oracle sql不接受IF EXISTS,否则我将进行if - update - else - insert查询。我看过了,MERGE但它仅适用于多个表。我该怎么办?

答案1

小编典典

MERGE不需要“多个表”,但确实需要查询作为源。这样的事情应该起作用:

MERGE INTO mytable dUSING (SELECT 1 id, ''x'' name from dual) sON (d.id = s.id)WHEN MATCHED THEN UPDATE SET d.name = s.nameWHEN NOT MATCHED THEN INSERT (id, name) VALUES (s.id, s.name);

或者,您可以在PL / SQL中执行此操作:

BEGIN  INSERT INTO mytable (id, name) VALUES (1, ''x'');EXCEPTION  WHEN DUP_VAL_ON_INDEX THEN    UPDATE mytable    SET    name = ''x''    WHERE id = 1;END;

c# – TSQL:带INSERT INTO SELECT FROM的UPDATE

c# – TSQL:带INSERT INTO SELECT FROM的UPDATE

所以我有一个旧的数据库,我正在迁移到一个新的数据库.新的具有略微不同但大多数兼容的模式.此外,我想从零重新编号所有表.

目前,我一直在使用我写的工具手动检索旧记录,将其插入新数据库,并更新旧数据库中的v2 ID字段,以在新数据库中显示其对应的ID位置.

例如,我从MV5.Posts中选择并插入MV6.Posts.插入后,我检索MV6.Posts中新行的ID,并在旧的MV5.Posts.MV6ID字段中进行更新.

有没有办法通过INSERT INTO SELECT FROM做这个UPDATE,所以我不必手动处理每个记录?我正在使用sql Server 2005,开发版.

解决方法

迁移的关键是做几件事情:
首先,不要做任何没有当前的备份.
第二,如果密钥正在更改,您需要至少临时存储新结构中的旧的和新的(永久地,如果密钥字段暴露给用户,因为它们可能被搜索以获取旧的记录).

接下来,您需要彻底了解与子表的关系.如果更改关键字段,所有相关表格也必须更改.这是存储旧密钥和新密钥的地方派上用场的地方.如果您忘记更改任何内容,数据将不再正确,无效.所以这是一个关键的一步.

挑选一些特别复杂数据的测试用例,确保为每个相关表格包含一个或多个测试用例.将现有值存储在工作表中.

要启动迁移,请使用旧表中的select插入到新表中.根据记录的数量,您可能需要循环访问批次(不能一次记录),以提高性能.如果新密钥是一个身份,您只需将旧密钥的值放在其字段中,并让数据库创建新密钥.

然后对相关的表进行相同的操作.然后使用表中的旧键值更新外键字段:

Update t2
set fkfield = newkey
from table2 t2
join table1 t1 on t1.oldkey = t2.fkfield

通过运行测试用例并将数据与迁移前存储的数据进行比较来测试迁移.彻底测试迁移数据至关重要,或者您无法确定数据与旧结构是一致的.移民是一个非常复杂的行动;它花费你的时间,并且非常有条不紊地做到这一点.

CQL(Cassandra)中是否有“IF EXISTS UPDATE ELSE INSERT”命令?

CQL(Cassandra)中是否有“IF EXISTS UPDATE ELSE INSERT”命令?

CQL(Cassandra)中是否有“IF EXISTS UPDATE ELSE INSERT”命令?如果没有,执行此类查询的最有效方法是什么?

解决方法

基本上你应该使用更新.在cassandra中,与关系世界相比,它们具有一些不同的机制,并且将作为隐含插入.

回答:
Does an UPDATE become an implied INSERT

mybatis+sqlServer 实现insertOrUpdate

mybatis+sqlServer 实现insertOrUpdate

这两天遇到一个头疼的问题,我们系统需要请求第三方数据,第三方收到请求后会生成相应的数据并入库,我们通过定时任务将第三方数据同步到我们数据库。当我们发送请求后第三方会立即返回一个值,我们会根据返回值去数据库更新同步过来的表字段,sql语句执行完了,没有任何错误,在同步表中查看同步的数据都有且where条件完全符合,但是就是没有将指定字段更新掉,最后通过多方对比,发现更新在前,插入在后。在此,贴出最简单的解决方法:

<insert id="insertOrUpdate">

if not exists (select 1 from table_name where column_name = XX)
    insert into table_name(id, update_time) values(1, getdate())
else
    update table_name set update_time = getdate() where id = 1

</insert>

先同步或是先更新没有确定,所以如果已存在则更新否则插入

 

2019年10月14号更新:

merge语法:

MERGE [ TOP ( expression ) [ PERCENT ] ]

[ INTO ] <target_table> [ WITH ( <merge_hint> ) ] [ [ AS ] table_alias ]

USING <table_source>

ON <merge_search_condition>

[ WHEN MATCHED [ AND <clause_search_condition> ]

THEN <merge_matched> ] [ ...n ]

[ WHEN NOT MATCHED [ BY TARGET ] [ AND <clause_search_condition> ]

THEN <merge_not_matched> ]

[ WHEN NOT MATCHED BY SOURCE [ AND <clause_search_condition> ]

THEN <merge_matched> ] [ ...n ]

[ <output_clause> ] [ OPTION ( <query_hint> [ ,...n ] ) ] ;

示例:

merge tb_backlog as target

using tb_logdb as source

on target.backlog_id = source.log_id

--目标表和源表匹配则执行update操作

when matched then

update set target.backlog_param = source.log_param

--目标表中没有,源表中存在则执行insert操作,将源表中存在而目标表不存在的记录插入到目标表中

when not matched then 

insert (backlog_id,backlog_name,backlog_url) values(source.log_id,source.log_name,source.log_url)

--目标表中存在,源表不存在则执行delete操作,删除目标表中的源表不存在的记录

when not matched by source then 

delete;

注意:结尾的分号不可少

Oracle DML语句(insert,update,delete) 回滚开销估算

Oracle DML语句(insert,update,delete) 回滚开销估算

以上脚本是在Oracle9.2上测试,Oracle对UNDO的处理非常复杂,这里介绍只是常用的一些DML产生UNDO估算方法,从估算公式可以看出,

一、Oracle DML SQL回滚逻辑简介

      数据库事务由1个或多个DML(insert,update,delete) SQL组成,我们知道Oracle数据库在进行DML操作需要使用UNDO表空间来保存事务回滚的信息,对于每种DML操作回滚的UNDO信息都不一样,大致如下:

insert操作很简单,只要保存记录插入到数据块及数据块内的槽号,回滚时只要根据数据块号及槽号做删除就可以了。

update操作需要保存记录位置,还需要保存变更的字段原内容,回滚时采用原值即可。

delete操作麻烦一些,不仅要保存记录位置,还需要将原有记录的内容全部保存下来,回滚时才能组成新的数据插入进去。     

如果表上有索引,则DML操作同时需要在UNDO表空间中保存索引相关的回滚信息。

DML操作主要有以下几方面的开销构成:
获取锁(CPU开销)
定位要变更的记录(离散IO开销)
记录回滚信息(CPU+IO开销)
变更记录(CPU开销)
记录重做日志(顺序IO开销)
数据块写入(异步离散IO开销)

因为DML操作过程中记录回滚信息占用了非常大的一块资源,为了更好的估算DML操作需要回滚空间的大小,本文介绍了一些常用操作的估算方法及验证示例。

二、如何查看事务UNDO使用空间

如何查看事务操作使用的UNDO空间,Oracle提供了系统视图V$TRANSACTION,里面保存了当前数据库活动事务的主要信息,我们可以用如下SQL来查看:

由于测试环境就我一个人使用,不存在并发,为简化操作,,忽略会活参数,简化的SQL如下:

select USED_UREC  from v$transaction;

通过START_UBAFIL及START_UBABLK我们可以dump回滚数据块的分析,如下所示:
alter system dump datafile START_UBAFIL block START_UBABLK;
dump好后再通过日志文件分析数据块内的详细信息,笔者也是通过这样的方法来确认计算公式,因为dump出来的内容比较复杂,是Oracle的具体实现细节,所以本文不介绍dump内容,有兴趣的同学可以自己测试。

三、测试准备

linux

关于oracle sql: update if exists else insert的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于c# – TSQL:带INSERT INTO SELECT FROM的UPDATE、CQL(Cassandra)中是否有“IF EXISTS UPDATE ELSE INSERT”命令?、mybatis+sqlServer 实现insertOrUpdate、Oracle DML语句(insert,update,delete) 回滚开销估算等相关内容,可以在本站寻找。

本文标签: