Oracle数据库的简单应用

本文内容包括:

1,数据类型

2,自增长ID

3,SQL语句

4,存储过程:基本语法,游标,异常处理

 

      对Oracle数据库的使用,我是个初学者。如果不是项目的需要,我可能连做初学者的机会也没有了。在小心翼翼、如履薄冰般地完成了数据库端的一些开发工作之后,我认为有必要把一些重要的和犯过错误的地方记录下来,给自己和大家参考。当然,我并不想做大而全的总结,也远没有达到这样的水平。

数据类型

      Oracle的数据类型和SQL Server有一些出入,这一点至少在数据类型的名称上就看得出来。常用的类型就是字符,数字,日期这些了。

      SQL Server 常用的字符类型有char,nchar,varchar,nvarchar,对于超长的字符,还有text,ntext等。 常用的数字类型有int,bigint,smallint,tinyint,decimal,float,real等。 日期是datetime和smalldatetime,还有一个时间戳类型timestamp,用法较特殊。其他的还有binary,bit,cursor,image,money,smallmoney,varbinary,uniqueidentifier等。其中uniqueidentifier对应了.Net中的GUID类型。

Oracle(9i)(注:这段摘自网络)
基本数据类型有:
char  用于描述定长的字符型数据,长度<=2000字节
varchar2  用于描述变长的字符型数据,长度<=4000字节
nchar  用来存储Unicode字符集的定长字符型数据,长度<=1000字节
nvarchar2  用来存储Unicode字符集的变长字符型数据,长度<=1000字节
number  用来存储整型或者浮点型数值
date  用来存储日期数据
long  用来存储最大长度为2GB的变长字符数据
raw  用来存储非结构化数据的变长字符数据,长度<=2000字节
long raw  用来存储非结构化数据的变长字符数据,长度<=2GB
rowid  用来存储表中列的物理地址的二进制数据,占用固定的10个字节
Blob  用来存储多达4GB的非结构化的二进制数据
clob  用来存储多达4GB的字符数据
nclob  用来存储多达4GB的Unicode字符数据
bfile  用来把非结构化的二进制数据存储在数据库以外的操作系统文件中
urowid  用来存储表示任何类型列地址的二进制数据
float  用来存储浮点数

 

自增长ID

      了解了以上数据类型之后,就可以建立自己的数据表了。慢~慢~慢~,我要建立一个类似SQL Server中的自增长列,Oracle中怎么没有IDENTITY的属性设置呢?

      其实在Oracle中,有类似的实现,只是稍微麻烦点,这个东西就是sequence。它定义了一个自增长的对象,每次查询了它的值以后,它会自增长1(1个step)。可以看看如下的创建sequence的sql语句

create sequence SEQ_BLOG_ID 
minvalue 1 
maxvalue 999999999999999999999999999 
start with 1 
increment by 1 
cache 20;

      要使用SEQ_BLOG_ID时,可以先定义一个变量V_SEQ_BLOG_ID NUMBER(10); 然后用执行SELECT SEQ_BLOG_ID.NEXTVAL INTO V_SEQ_BLOG_ID FROM DUAL;就可以的到SEQ_BLOG_ID的当前值了。很明显,这个当前值存入了变量V_SEQ_BLOG_ID中,当然,你也可以不定义变量而直接使用sql语句查看sequence的当前值。

 

SQL语句

      Oracle和SQL Server当然都支持标准的SQL语句,但是我们常常需要使用一些“个性化”的SQL语句,以达到简洁、高效的效果。我就遇到了一些这样的情况,下面举个例子:

      在SQL Server中,对于这样的情景,我们可能会使用update xxx from xxx语句:两个表,Student表存储了学生的信息,其中有ID,Name,Score等字段;StudentScore(成绩表),包括StudentID,EnglishScore,MathScore…等字段。要求把StudentScore中学生的总成绩根据更新到Student表的Score中。

      一种方法是写一个循环,遍历每个学生,然后将他们的各门功课成绩相加,让后根据StudentScore.StudentID=Student.ID更新到Student.Score。

      这样做显然比较麻烦,可以考虑使用update Student set Student.Score=StudentScore.EnglishScore +StudentScore.MathScore +… from StudentScore where StudentScore.StudentID=Student.ID;一句话就解决了战斗。

      同样的,要找Oracle中实现上述的功能,用一句sql解决问题,就要这样来了:update Student  set Student.Score=(select StudentScore.EnglishScore +StudentScore.MathScore +… from StudentScore where StudentScore.StudentID=Student.ID) where exists(select 1 from StudentScore where StudentScore.StudentID=Student.ID);

       简单解释一下,这个sql语句的主干是: update Student set  Student.Score=成绩合计 where 存在学号相等的学生。 可以这样理解:如果存在学号相等的学生,那么就把成绩的合计值更新到对应的Student的Score字段。这里的对应的是怎么实现的呢?就是从句(select StudentScore.EnglishScore +StudentScore.MathScore +… from StudentScore where StudentScore.StudentID=Student.ID)中的where后的部分StudentScore.StudentID=Student.ID。

      值得一提的是,Oracle允许一次update多列的值,如update (column1,column2,…) =(select col1,col2,…) from xxx where xxx,但要求等号两端列的个数和对应数据类型相同。另外如果作为值的记录数大于被更新的记录数,会报异常。

      这里还有个语句是关于select  into 的。我们知道这个语句是从表里选出某些字段的值,放入into后面的变量里。在SQL Server中,如果要选出10个字段的值,我们就得定义10个变量。Oracle提供了一种好用的类型——行类型。

定义行类型

declare curStudentScore_Row StudentScore%rowtype;

使用行类型

select * into curStudentScore_Row from StudentScore where StudentID =1;

totalScore :=curStudentScore_Row.EnglishScore + curStudentScore_Row.MathScore +…;

      怎么样,很方便吧!

 

存储过程

      在Oracle中,准确的说法应该是“过程”(Procedure)。编写过程常见的问题是

  • 过程结构,命名,参数。这个查看一下已有的过程就一目了然了。注意begin 和end成对出现。
  • 变量定义和赋值。就像在前面“自增长ID”一段中所述的那样V_SEQ_BLOG_ID NUMBER(10); 就是定义了一个名称为V_SEQ_BLOG_ID,类型为NUMBER(10)的变量。注意别忘了分号(;)。赋值使用V_SEQ_BLOG_ID :=100;的形式,冒号等号(:=)。
  • 条件语句

if xxx then

begin

xxx

end;

end if;

  • 循环

while xxx loop

begin

xxx

end;

end loop;

或者

for xxx in xxx loop

begin

xxx

end;

end loop;

  • 游标

        定义游标

declare cursor curStudentScore is select * from StudentScore a;

使用游标的方式有几种,一种是使用SQL Server中的Fetch;这里介绍一个最简单的,使用for语句(这里curStudentScore_Row不需要预先定义)

for curStudentScore_Row in curStudentScore loop
begin

//在这里可以直接通过curStudentScore_Row.EnglishScore的形式访问StudentScore中的字段EnglishScore的值。

end;

end loop;

使用完后,游标也不需要显式地关闭。真是方便啊!

 

  • 异常

      在SQL Server(2005)中,捕获异常是通过try… catch…来实现的,可以参考前面我的一篇文章SQL Server 2005存储过程开发的一点经验。在Oracle中,定义异常处理的语句是形如下面的语句

exception  
when no_data_found then xxx;

when others then return;

      说明一下,当过程中的某个语句发生异常时,会进入其后的最近一个exception,并根据when后的条件,进入相应的处理逻辑。异常处理完毕后,会继续执行异常代码块后面的代码(如果有)。

      以上只是对项目中的一些经验的小结,可能存在不正确的地方,请多包涵。

 

posted @ 2009-06-04 12:44  春风沉醉的晚上  阅读(636)  评论(0编辑  收藏  举报