Oracle存在修改,不存在插入记录
接触编程以来,在数据存储方面一直用的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 = '')
insert into Account(AccountID,AccountName) values('','Sam Xiao')
else
update Account set AccountName = '肖建' where AccountID = ''
这种代码,我们在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;
begin
select 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 = '';
IF SQL%NOTFOUND THEN
insert into account(AccountID,AccountName) values('','添加-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('','添加-b');
exception
when DUP_VAL_ON_INDEX then begin
update account set AccountName = '修改-b' where AccountID = '';
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='');
if t_count< 1 then
dbms_output.put_line('添加');
insert into account(AccountID,AccountName) values('','添加-11');
else
dbms_output.put_line('修改');
update account set AccountName = '修改-11' where AccountID = '';
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 = '';
exception
when no_data_found then begin
--dbms_output.put_line('添加');
insert into account(AccountID,AccountName) values('','添加-8');
end;
when others then
begin
--dbms_output.put_line('修改');
update account set AccountName = '修改-8' where AccountID = '';
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 '' 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存在修改,不存在插入记录的更多相关文章
- oracle创建序列,并插入记录
Oracle序列创建和使用创建序列 语法 CREATE SEQUENCE 序列名 [相关参数] 参数说明 INCREMENT BY : 序列变化的步进,负值表示递减.(默认1) START WITH ...
- MsSql 游标 修改字段两个表关联 表向另个表插入记录
-- 方法1:游标-- 声明变量DECLARE @SystemUserId AS UNIQUEIDENTIFIER -- 声明游标DECLARE C_SystemUser CURSOR FAST_FO ...
- java读取文件批量插入记录
只是一个例子,方便以后查阅. import ey.db.oracle.OracleHelper; import ey.db.type.*; import java.io.BufferedReader; ...
- Oracle 增加修改删除字段
Oracle 增加修改删除字段 添加字段的语法:alter table tablename add (column datatype [default value][null/not null],…. ...
- Mysql避免重复插入记录方法
一.mysql replace用法 1.replace into replace into table (id,name) values('1','aa'),('2','bb') 此语句的作用是向 ...
- 安装Oracle后修改IP总结(转载)
转载自:http://blog.csdn.net/bleibo/article/details/5447198 安装Oracle后修改IP总结(转载) 针对ORACLE 10G 在安装完后,修改IP ...
- 插入记录INSERT(二十五)
插入记录INSERT 我们先来看第一个操作:INSERT 实际上在mysql当中一共存在着3种不同的insert语句,我们先来看第一种.它的语法结构如下: 一.插入记录 INSERT [INTO] t ...
- MyBatis 插入记录同时获取主键
MyBatis 插入记录同时获取主键 MyBatis 插入记录同时获取主键的系统界面 useGeneratedKeys 属性 keyProperty 属性 keyColumn 属性 selectKey ...
- Oracle删除修改字段
Oracle 增加修改删除字段 添加字段的语法:alter table tablename add (column datatype [default value][null/not null],…. ...
- MyBatis获取插入记录的自增长字段值
在Mybatis Mapper文件中添加属性“useGeneratedKeys”和“keyProperty”,其中keyProperty是Java对象的属性名! <insert id=" ...
随机推荐
- Jquery基础知识
//使用$操作得到的对象,都是Jquery对象 如何把Jquery对象转换成dom对象?$abc 方法1:var div = $div.get(0) 方法2:var div = $div[0] 如何把 ...
- EXCEL文件格式不匹配,或者已经损坏,除非信任来源
修改注册表解决: .打开注册表编辑器 方法:开始 -> 运行 -> 输入regedit -> 确定 .找到注册表子项 HKEY_CURRENT_USER\Software\Micro ...
- js模块和级联
1.模块 模块模式的一般形式是:一个定义了私有变量和函数的函数,利用闭包创建可以访问私有变量和函数的特权函数,最后返回这个特权函数,或者把它们保存到一个可访问的地方.使用模块模式就可以摒弃全局变量的使 ...
- Jquery插件开发精品教程
最开始接触jquery对他提供的各种插件总是十分有兴趣,但是总是不理解为什么这样写,从网络上查询了很久终于找到这篇文章,讲解的很详细,分享给大家. 要说jQuery 最成功的地方,我认为是它的可扩展性 ...
- 1282 - Leading and Trailing ---LightOj1282(快速幂 + 数学)
http://lightoj.com/volume_showproblem.php?problem=1282 题目大意: 求n的k次方的前三位和后三位数然后输出 后三位是用快速幂做的,我刚开始还是不会 ...
- POST 500 Internal Server Error
今天调试公司web后台时发现一个POST 500 Internal Server Error的错误. 本来VS本地调试没有发现这个问题,然后发布到服务器时才出现了.然后找了好久没找到什么原因,再仔细在 ...
- webview loadUrl() 弹出系统浏览器解决办法
有很多时候,我们请求的网站会直接跳转到一个位置,这样会直接全屏浏览器加载被跳转的网页,或者弹出浏览器选择(除了系统的,你还自己安装了其他浏览器). 于是解决办法的原理就是,在webview中跳转. 办 ...
- Html5应用程序缓存ApplicationCache
应用缓存机制可以参考http://www.w3school.com.cn/html5/html_5_app_cache.asp,不再赘述.利用此机制,html5游戏可以实现和native app类似的 ...
- 最常用的reset代码
/*css reset code */ /**** 文字大小初始化,使1em=10px *****/body { font-size:12px;} /*字体边框等初始化*/body,div,dl,dt ...
- 快手4.0 (KSCAD)
快手 4.0 (KSCAD) 是一款简单易用的矢量绘图软件,其功能和Visio类似,可以绘制工艺流程图,流程图.组织结构图.网络拓扑图.思维导图.商业图表等. 经过二次开发,可以应用于各种领域的图形化 ...