接触编程以来,在数据存储方面一直用的MS SQL。Oracle这名字对我来说是如此的熟悉,但是对其内容却很陌生,最近公司的一个项目用起了Oracle,所以也开始高调的用起了Oracle。在没有接触Oracle之前,听很多人都说Oracle的语法与MS SQL差不多,我在朋友圈里也帮着吹嘘这个观点。告诉朋友们,Oralce与MSSQL差不多,确实,貌似一看CRUD几乎没区别,但是当你慢慢深入了解Oracle的时候,你会发现这个观点有点愚蠢。

  我们先来说个很常见的开发案例,有一张Account表,有两个字段分别为AccountID, AccountName,其中AccountID为主键,往这个表中插入数据,以主键为唯一标识,表中存在这条记录则修改,不存在则添加。

  一:在MS SQL中

  首先创建一个Account表,为了简单,我们都以nvarchar(50)作为字段类型。具体代码如下:

if object_id(N'Account',N'U') is not null
drop table Account
create table Account
(AccountID nvarchar(50) primary key  not null,AccountName nvarchar(50)
)

  接下来我们要做的事就是往这个表中插入数据

if not exists (select * from Account where AccountID = '1') insert into Account(AccountID,AccountName) values('1','Sam Xiao')
elseupdate Account set AccountName = '肖建' where AccountID = '1'

  这种代码,我们在SQL中是写的如此自然和熟练,但是你在Oracle中,你用这种方式来写,你会遇上一些麻烦。那现在我们在Oracle中来演示如何完成这样的需求。

  二:在Oracle中

  首先是创建表有着细微的区别,判断一个表是否存在,习惯了MS SQL的OBJECT_ID('对象表','对象类型')的童鞋们,你们是不是想到Oracle中也应该有这样的功能呢?遗憾了,Oracle中没有此类函数来判断一个表是否存在,那就只能通过委婉的方式来实现,MS SQL中有类似于 Select Name From SysObjects Where XType='U'这样的数据库表,那对应的Oracle中就有了select  * from user_tables,通过查询系统表,判断这个表在数据库中是否存在,如果存在就删除,然后再创建。

declare num number;
beginselect count(1) into num from user_tables where table_name='ACCOUNT';   if num > 0 then   dbms_output.put_line('存在!');execute immediate 'drop table ACCOUNT '; end if;   execute immediate 'create table Account(AccountID nvarchar2(50) primary key,AccountName nvarchar2(50) )';  dbms_output.put_line('成功创建表!');
end; 

与MS SQL创建一个表对比,是不是还是有一些显微的差异呢?答案当然是肯定的。
  这个演示是前奏,现在来开始我们今天的主题,在Oracle中,表创建成功了,现在我要往这个表中插入数据,如果新插入的数据在表中存在则修改,不存在则插入,我在网上一搜,惊奇的发现Oracle中的exists()函数是判断两个数据集合的交集是否存在,与MS SQL有一定的区别。这样的对比虽然会显的不专业,但是我还是有对比和发表自己观点自由。于是我在网上疯狂的搜索Oracle在这个问题上的解决方案,总结了以下几种方案,以供大家选择:

1:隐式游标法 SQL%NOTFOUND   SQL%FOUND

SQL%NOTFOUND 是SQL中的一个隐式游标,在增删查改的时候自动打开,如果有至少有一条记录受影响,都会返回false,这就就巧妙的构思出了第一种解决方案:

begin
update account set AccountName = '修改-a' where AccountID = '5';
IF SQL%NOTFOUND THENinsert into account(AccountID,AccountName) values('5','添加-b');
END IF;
end;

先根据唯一ID到数据表中修改一条记录,如果这条记录在表中存在,则修改,并且SQL%NOTFOUND返回false。如果修改的记录不存在,SQL%NOTFOUND返回true,并且执行插入语句。

2:异常法 DUP_VAL_ON_INDEX

当Oracle语句执行时,发生了异常exception进行处理

begin
insert into account(AccountID,AccountName) values('6','添加-b');
exception
when DUP_VAL_ON_INDEX then begin
update account set AccountName = '修改-b' where AccountID = '6';
end;
end;

当往表中插入一条数据,因为表中有主键约束,如果插入的数据在表中已经存在,则会抛出异常,在异常抛出后进行修改。

3:虚拟表法  dual

dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。

declare t_count number;
begin
select count(*) into t_count from dual where exists(select 1 from account where AccountID='11');
if t_count< 1 thendbms_output.put_line('添加');insert into account(AccountID,AccountName) values('11','添加-11');
elsedbms_output.put_line('修改');update account set AccountName = '修改-11' where AccountID = '11';end if;
end;

先声明一个变量t_count,表dual表的值赋给t_count,如果这个值小于1,表示记录不存在,进行插入操作,反之,存在就进行修改操作。

4:no_data_found法

先查找要插入的记录是否存在,存在则修改,不存在则插入。具体的实现如下:

declare t_cols number;
begin
select AccountName into t_cols from account where AccountID = '8';
exception
when no_data_found then begin --dbms_output.put_line('添加');insert into account(AccountID,AccountName) values('8','添加-8');
end;
when others then begin--dbms_output.put_line('修改');update account set AccountName = '修改-8' where AccountID = '8';
end;
end;

5:merge法

先来看一下merge的语法,

MERGE INTO table_name alias1
USING (table|view|sub_query) alias2
ON (join condition)
WHEN MATCHED THEN   UPDATE table_name SET col1 = col_val1
WHEN NOT MATCHED THEN   INSERT (column_list) VALUES (column_values);

看了merge的语法后,依葫芦画瓢对于我这种抄袭的人来说已经不是什么难事了。

merge into Account t1
using (select '3' AccountID,'肖文博' AccountName from dual) t2
on (t1.AccountID = t2.AccountID)
when matched then  update set t1.AccountName = t2.AccountName
when not matched then  insert values (t2.AccountID, t2.AccountName);
commit; 

至此介绍了五种方法来解决我提出的问题。问题是小,但是已经牵涉了Oracle的好几个知识点。最后你与MS SQL相比,在用法上还是有很大的差异。至此,仁者见仁智者见智。

如果这篇博客对你有帮助,不要忘记了右下角的【推荐】  。

Oracle存在修改,不存在插入记录相关推荐

  1. oracle创建序列,并插入记录

    Oracle序列创建和使用 创建序列 语法 CREATE SEQUENCE 序列名 [相关参数] 参数说明 INCREMENT BY  : 序列变化的步进,负值表示递减.(默认1) START WIT ...

  2. ORACLE向表插入记录的顺序和读取记录的次序一样吗??

    向表插入记录的顺序和读取记录的次序一样吗?? [问题点数:30分,结帖人wh62592855] 收藏帖子 回复 右鞋左穿 结帖率 100% SQL code? 1 2 3 4 5 6 7 8 9 10 ...

  3. oracle表修改语句,Oracle的常用修改表及字段的语句

    单行注释:-- 多行注释:/* */ Oracle中修改表结构 增加字段 ALTER TABLE table_name ADD column_name data_type; 删除字段 ALTET TA ...

  4. oracle r修改表名,oracle中修改表名

    <<>> answer1: ALTER TABLE old_table_name RENAME TO new_table_name;(大写为系统命令) answer2: SQL ...

  5. Oracle-创建Oracle用户修改密码并赋权限

    添加用户:(随着用户的创建,自动产生与用户同名的schema) CREATE USER "TESTER" PROFILE "DEFAULT" IDENTIFIE ...

  6. Mongodb源码分析--插入记录及索引B树构建

    在之前的一篇文章中,介绍了assembleResponse函数(位于instance.cpp第224行),它会根据op操作枚举类型来调用相应的crud操作,枚举类型定义如下:      enum Op ...

  7. 表的插入、更新、删除、合并操作_4_同时往多个表插入记录

    同时往多个表插入记录 需求描述 需求:从dept表里插入数据到3张表,当loc是NEW YORK和BOSTON时向dept_east表中插入,当当loc是CHICAGO时向dept_mid表中插入,其 ...

  8. 向表插入记录的顺序和读取记录的次序一样吗??

    向表插入记录的顺序和读取记录的次序一样吗?? [问题点数:30分,结帖人wh62592855] 收藏帖子 回复 右鞋左穿 结帖率 100% SQL code? 1 2 3 4 5 6 7 8 9 10 ...

  9. 使用SQL Server 获取插入记录后的ID(自动编号)

    使用SQL Server 获取插入记录后的ID(自动编号) jingxian 本篇文章是对使用SQL Server获取插入记录后的ID(自动编号)的方法进行了详细的分析介绍,需要的朋友参考下 最近在开 ...

  10. Oracle如何删除表中重复记录

    1  引言 在对数据库进行操作过程中我们可能会遇到这种情况,表中的数据可能重复出现,使我们对数据库的操作过程中带来读诸多不便,那么怎么删除这些重复没有用的数据呢? 平时工作中可能会遇到当试图对库表中的 ...

最新文章

  1. php中的网页漂浮代码,JavaScript_Javascript实现带关闭按钮的网页漂浮广告代码,复制代码 代码如下: html - phpStudy...
  2. mysql网页后台_MySQL(PHP网站后台数据库)
  3. VBScript在服务器上创建目录
  4. 批量管理Linux服务器,命令行工具Omnitty
  5. js中如果无法获取某个html属性,例如自定义了一个dir属性,但获取总是为空,尝试换个词,因为可能什么关键词冲突了。...
  6. LeetCode 1236. 网络爬虫(BFS/DFS)
  7. LeetCode 第 24 场双周赛(326/1898,前17.2%)
  8. Oracle使用Sql把XML解析成表(Table)的方法
  9. java 抽象类的匿名类_Java匿名内部类(通过继承抽象类来实现)
  10. 联想拯救者y空间_联想拯救者 R9000X 笔记本 GTX 1650 Ti 配置被砍
  11. section和div有什么区别?
  12. 【java学习之路】(javaWeb篇)007.正则表达式专题
  13. MySQL安装配置+Navicat安装配置
  14. ubuntu18.04桌面美化
  15. CodeLite 16无法自动代码补全
  16. js中元素样式设置的六种方法
  17. JavaWeb项目——博客系统
  18. 基于LM的双目图像校准算法源码第一部分
  19. Windows 8系统中LOL登陆错误出现的服务器未响应怎么处理?
  20. yolov5 + second_classify -- 代码

热门文章

  1. 使用Boost.Compute类在GPU上设置和运行简单的矢量加法内核
  2. ITK:与矢量型图像应用GradientRecursiveGaussianImageFilter
  3. ITK:建立一个Hello World程序
  4. VTK:图片之ImageRotate
  5. OpenCV均值漂移的跟踪mean-shift based tracking的实例(附完整代码)
  6. DelegateModel QML类型
  7. C++实现二分查找(附完整源码)
  8. C++数据结构之链式结构
  9. mysql数据库引擎博客_mysql 数据库引擎常识全集
  10. Flink-Table StreamTableEnvironment基础知识