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

在我眼中的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  

相关推荐

    oracle SQL查询工具

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

    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框架的客户端驱动,它允许...

    一个oracle 用户下创建多个oracle 实例

    为了使我们的 Oracle 实例能够与外部世界通信,我们需要配置 TNS。 在我们的示例中,我们需要在 TNS 配置文件中添加新的实例信息,以便于其他客户端能够连接到我们的 Oracle 实例。 五、监听的配置 监听是 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

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

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

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

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

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

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

    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日发布。在本手册的版本历史中,还包含了不同版本的...

    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

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

    在数据库连接方面,OracleClient-21C支持多种连接方式,如TCP/IP、Named Pipes、Shared Memory等,其中TNS(Transparent Network Substrate)是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...

Global site tag (gtag.js) - Google Analytics