`
javawebsoa
  • 浏览: 424242 次
社区版块
存档分类
最新评论

在我眼中的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 = '1') 
    insert into Account(AccountID,AccountName) values('1','Sam Xiao')
else
    update 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;   
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 与Oralce的易用性了。这样肤浅的对比虽然会显的不专业,但是我还是有对比和发表自己观点自由。于是我在网上疯狂的搜索Oracle在这个问题上的解决方案,总结了以下几种方案,以供大家选择:

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

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

begin
update account set AccountName = '修改-a' where AccountID = '5';
IF SQL%NOTFOUND THEN
   insert 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 then
  dbms_output.put_line('添加');
  insert into account(AccountID,AccountName) values('11','添加-11');
else
  dbms_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相比,在用法上还是有很大的差异。至此,仁者见仁智者见智。

4
0
分享到:
评论
3 楼 yuvyuvyuv 2013-12-04  
Oracle中有exists关键字...
2 楼 903293718 2013-12-04  
Oracle中没有exists()函数?
1 楼 hngmduyi 2013-12-03  

相关推荐

    navicat链接oracle文件,OCI文件 oracle12版本 OCI文件链接oracle12

    Oracle数据库是世界上最流行的数据库管理系统之一,而Navicat是一款强大的数据库管理工具,支持多种数据库类型,包括Oracle。在本文中,我们将深入探讨如何使用Navicat连接到Oracle 12c数据库,以及oci文件在其中的...

    navicat链接oracle文件,OCI文件 oracle11版本 OCI文件链接oracle11

    Oracle数据库是世界上最流行的数据库管理系统之一,而Navicat是一款强大的数据库管理工具,支持多种数据库类型,包括Oracle。在本文中,我们将深入探讨如何使用Navicat连接到Oracle数据库,特别是涉及Oracle Call ...

    基于C#连接Oracle数据库Oracle.ManagedDataAccess

    本篇将详细讲解如何使用C#通过Oracle.ManagedDataAccess库实现与Oracle数据库的连接,无需在本地安装完整的Oracle数据库。 首先,Oracle.ManagedDataAccess是Oracle公司提供的一个纯.NET框架的客户端驱动,它允许...

    Veeam 备份恢复oracle数据库详细配置文档

    在开始备份恢复 Oracle 数据库之前,需要在 Oracle 源机和 Oracle 恢复目标机上设置好 host 解析。为此,需要在 Oracle 源机和 Oracle 恢复目标机上编辑 hosts 文件,添加相应的 host 解析信息。 二、推送 Oracle ...

    Python连接oracle工具cx_Oracle官方文档

    在安装cx_Oracle之前,首先需要安装Python环境。cx_Oracle支持Python 2.7以及3.4及以上版本。安装cx_Oracle最简单的方法是使用pip工具。如果在安装过程中遇到问题,可以参考“故障排除”部分。cx_Oracle使用ODPI-C库...

    OracleClient-18C Oracle客户端,包括windows和Linux

    这个版本适用于Windows和Linux操作系统,确保了跨平台的兼容性,使得开发者和系统管理员可以在多种环境下无缝地管理和访问Oracle数据库。 在Windows环境中,OracleClient通常包含oci.dll等核心库文件,以及...

    Oracle课程设计 Oracle项目实例 Oracle编程

    Oracle是世界上最广泛使用的数据库管理系统之一,它在企业级数据存储、管理和分析方面有着卓越的表现。本Oracle课程设计和项目实例集旨在为初学者提供深入学习和实践的平台,帮助他们掌握Oracle的核心技术和实际应用...

    oracle jdbc 驱动,支持oracle 19c

    oracle jdbc 驱动,支持oracle 19c

    oracle.jdbc.driver.oracledriver Oracle JDBC驱动包 ojdbc6

    ojdbc6.jar包含所有必要的类和接口,允许开发者在Java 6环境中实现与Oracle数据库的高效连接和数据操作。 Oracle JDBC驱动提供了多种功能,例如: - **数据库连接**:通过`java.sql.DriverManager`类获取数据库...

    SqlDbx连接oracle

    在没有完整Oracle客户端的情况下,可能需要手动配置这个文件来指定要连接的Oracle实例。 总的来说,SqlDbx通过Oracle Instant Client的库文件实现了对Oracle数据库的连接,使得用户无需安装庞大的Oracle客户端软件...

    Oracle 9i Client (Oracle 9i 客户端) 简化版 (不安装Oracle客户端,也可以使用PLSQL Developer)

    Oracle 9i Client (Oracle 9i 客户端) 简化版 (不安装Oracle客户端,也可以使用PLSQL Developer 不用安装Oracle客户端也可以使用PLSQL Developer 绿色! 安全! 轻便! 可靠! 1、本软件可作为简单的Oracle9i客户端...

    cx_Oracle使用手册

    请注意,cx_Oracle.clientversion()是一个扩展方法,仅在Oracle 10g Release 2及以上版本中可用。 文档的发布信息显示,cx_Oracle版本为5.2.1,并于2016年10月14日发布。在本手册的版本历史中,还包含了不同版本的...

    OracleClient-19C Oracle客户端,包括windows和Linux

    这个压缩包包含的Oracle Client适用于Windows和Linux操作系统,使得开发者和管理员可以在不同的平台上访问和管理Oracle数据库。 在Windows环境下,Oracle Client通常以图形化界面的形式提供,例如SQL*Plus、Oracle ...

    oracle10G和oracle11G的OCI.dll

    Oracle 10G是Oracle公司在2003年发布的关系型数据库管理系统,而Oracle 11G则是在2007年推出的升级版。这两个版本之间的主要差异体现在性能、可扩展性、安全性以及管理功能等方面。 1. OCI接口:OCI提供了丰富的API...

    Mysql转Oracle软件 DBMover for Mysql to Oracle

    使用DBMover可以灵活定义Mysql和Oracle之间表和字段的对照关系,也可以在DBMover创建一个查询,把查询结果当作源表转入到Oracle中。 Dbmover for Mysql to Oracle 可以定时,定周期自动运行。 支持 Oracle 8i 以后...

    sap oracle sap oracle sap oracle sap oracle

    sap oracle sap oracle sap oracle

    oracle 使用命令创建oracle数据库

    ORACLE_HOME=$ORACLE_BASE/oracle ORACLE_SID=hsj PATH=$ORACLE_HOEM/bin:$PATH; LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH LD_LIBRARY_PATH  3...

    OracleClient-21C Oracle客户端,包括windows和Linux

    在数据库连接方面,OracleClient-21C支持多种连接方式,如TCP/IP、Named Pipes、Shared Memory等,其中TNS(Transparent Network Substrate)是Oracle常用的一种网络通信协议,它提供了一种透明的方式来定位和访问...

    oracle SQL查询工具

    oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具oracle SQL查询工具...

Global site tag (gtag.js) - Google Analytics