存储过程oracle详细使用手册带图_第1页
存储过程oracle详细使用手册带图_第2页
存储过程oracle详细使用手册带图_第3页
存储过程oracle详细使用手册带图_第4页
存储过程oracle详细使用手册带图_第5页
已阅读5页,还剩65页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Oracle存储过程总结

1、创建存储过程

createorreplaceproceduretest(var_name_lintype,var_name_2outty

pe)as

一声明变量(变量名变量类型)

begin

一存储过程的执行体

endtest;

打印出输入的时间信息

E.g:

createorreplaceproceduretest(workDateinDate)is

begin

dbms_output.putlinejTheinputdateis:||to_date(workDate,yyyy-mm-d

d));

endtest;

2、变量赋值

变量名:=值;

E.g:

createorreplaceproceduretest(workDateinDate)is

xnumber(4,2);

begin

X:二1;

endtest;

3、判断语句:

if比较式thenbeginend;endif;

E.g

createorreplaceproceduretest(xinnumber)is

begin

ifx>0then

begin

x:=0-x;

end:

endif;

ifx=0then

begin

x:=1;

end;

endif;

endtest;

4、For循环

For…in...LOOP

一执行语句

endLOOP;

(1)循环遍历游标

createorreplaceproceduretest()as

Cursorcursorisselectnamefromstudent;

namevarchar(20);

begin

fornameincursorLOOP

begin

dbmsoutput,putline(name);

end;

endLOOP;

endtest;

⑵循环遍历数组

createorreplaceproceduretest(varArrayinmyPackage.TestArray)a

s

一(输入参数varArray是自定义的数组类型,定义方式见标题6)

inumber;

begin

i:=1;一存储过程数组是起始位置是从1开始的,与java、C、C++等语言

不同。由于在Oracle中本是没有数组的概念的,数组其实就是一张

-表(Table),每个数组元素就是表中的一个记录,所以遍历数组时就相称于从表

中的第一条记录开始遍历

foriin1..varArray.countLOOP

dbms_output.putline^TheNo.||i||recordinvarArrayis:||varArray

⑴);

endLOOP;

endtest;

5>While循环

while条件语句LOUP

begin

end;

endLOOP;

E.g

createorreplaceproceduretest(iinnumber)as

begin

whilei<10LOOP

begin

i:=i+1;

end;

endLOOP;

endtest;

6、数组

一方面明确一个概念:Dracle中本是没有数组的概念的,数组其实就是一张表(T

able),每个数组元素就是表中的一个记录。

使用数组时,用户可以使用Oracle已经定义好的数组类型,或可根据自己的需

要定义数组类型。

(1)使用Oracle自带的数组类型

xarray;一使用时需要需要进行初始化

e.g:

createorreplaceproceduretest(youtarray)is

xarray;

begin

x:=newarray();

y:=x;

endtest;

⑵自定义的数组类型(自定义数据类型时,建议通过创建Package的方式实现,

以便于管理)

E.g(自定义使用参见标题4.2)createorreplacepackagemyPackageis

-Publictypedeclarationstypeinfoisrecord(nameva

rchar(20),ynumber);

typeTestArrayistableofinfoindexbybinary_integer;一一此处

声明了一个TestArray的类型数据,其实其为一张存储Info数据类型的Table

而已,及TestArray就是一张表,有两个字段,一个是

name,一个是y。需要注意的是此处使用了Indexbybinary_integer编制该T

able的索引项,也可以不写,直接写成:typeTestArrayis

tableofinfo,假如不写的话使用数组时就需要进行初始化:varArraymyPac

kage.TestArray;varArray:=newmyPackage.TestArray();

endTestArray;

7.游标的使用Oracle中Cursor是非常有用的,用于遍历临时表中的查询结果.

其相关方法和属性也很多,现仅就常用的用法做一二介绍:

(DCursor型游标(不能用于参数传递)

createorreplaceproceduretest()is

cusor_lCursorisselectstdnamefromstudentwhere…;--Curso

r的使用方式1cursor_2Cursor;

begin

selectclass_nameintocursor_2fromclasswhere…;一Cursor的使

用方式2

可使用ForxincursorLOOP....endLOOP;来实现对Cursor的遍历

endtest;

(2)SYS_REFCURSOR型游标,该游标是Oracle以预先定义的游标,可作出参数进

行传递

createorreplaceproceduretest(rsCursoroutSYSREFCURSOR)is

cursorSYSREFCURSOR;namevarhcar(20);

begin

OPENcursorFORselectnamefromstudentwhere...-SYS_REFCURSOR只

能通过OPEN方法来打开和赋值

LOOP

fetchcursorintoname-SYSREFCURSOR只能通过fetchinto夹打

开和遍历exitwhencursor%N0TF0UND;-SYSR

EFCLRSOR中可使用二人状态屈性:

-一%NOTFOUND(未找到记录信息)财OUND(找到记录信息)

一一%ROWCOUNT(然后当前游标所指向的行位置)

dbms_output.putline(name);

endLOOP;

rsCursor:=cursor;

endtest;

下面写一个简朴的例子来对以上所说的存储过程的用法做一个应用:

现假设存在两张表,一张是学生成绩表(studnet),字段为:stdld,math,artic

le,language,music,sport,total,average,step

一张是学生课外成绩表(out_school),

字段为:stdld,parctice,comment

通过存储过程自动计算出每位学生的总成绩和平均成绩,同时,假如学生在课外

课程中获得的评价为A,就在总成绩上加20分。

createorreplaceprocedureautocomputer(stepinnumber)is

rsCursorSYS_REFCURSOR;

commentArraymyPackage.myArray;

mathnumber;

articlenumber;

1anguagenumber;

musicnumber;

sportnumber;

totalnumber;

averagenumber;

stdldvarchar(30);

recordmyPackage.stdlnfo;

inumber;

begin

i:=1;

get_coniment(commentArray);一调用名为get_comment()的存储过程获取学生

课外评分信息

OPENrsCursorforselectstdld,math,article,language,music,sportfrom

studenttwheret.step=step;

LOOP

fetchrsCursorintostdld,math,article,language,music,sport;exitwhe

nrsCursor%NOTFOUND:

total:=math+article+language+music+sport;

foriin1..commentArray.countLOOP

record:=commentArray(i);

ifstdTd=record,stdldthen

begin

ifrecord,comment='A'then

begin

total:=total+20;

gotonext;一使用goto跳出for循环

end;

endif;

end;

endif;

endLOOP;

<<continue>>average:=total/5;

updatestudenttsett.total=totalandt.average=averagewheret.

stdld=stdTd;

endLOOP;

end;

endautocomputer;

一取得学生评论信息的存储过程

createorreplaceprocedureget_comment(conmentArrayoutmyPackage.my

Array)is

rsSYS_REFCURSOR;

recordmyPackage.stdlnfo;

stdTdvarchar(30);

commentvarchar(1);

inumber;

begin

openrsforselectstdld,commentfromout_school

i:=1;

LOOP

fetchrsintostd?d,comment;exitwhenrs%N0TF0UND;

record.stdld:=stdld;

record,comment:=comment:

recommentArray(i):=record;

i:=i+1;

endLOOP;

endgetcomment;

一定义数组类型myArray

createorreplacepackagemyPackageisbegin

typestdlnfoisrecord(stdldvarchar(30),commentvarchar(1));

typemyArrayistableofstdlnfoindexbybinary_integer;

endmyPackage;

项目中有涉及存储过程对字符串的解决,所以就将在网上查找到的资料汇总,做一个信

息拼接式的总结。

以下信息均来自互联网,贴出来一则自己保存以待以后使用,一则供大家分享。

字符函数一一返同字符值

这些函数全都接受的是字符族类型的参数(QIR除外)并且返回字符值.

除了特别说明的之外,这些函数大部分返回VARCHAR2类型的数值.

字符函数的返回类型所受的限制和基本数据库类型所受的限制是相同的。

字符型变量存储的最大值:

VARCHAR2数值被限制为2023字符(ORACLE8中为4000字符)

CHAR数值被限制为255字符(在0RACLE8中是2023)

long类型为2GB

Clob类型为4GB

1、CHR

语法:chr(x)

功能:返回在数据库字符集中与X拥有等价数值的字符0CHR和ASCII是一对反函数。通过

CHR转换后的字符再通过ASCII转换又得到了本来的字

符。

使用位置:过程性语句和SQL语句。

2、CONCAT

语法:CONCAT(stringl.string2)

功能:返回stringl,并且在后面连接string2。

使用位置:过程性语句和SQL语句。

3、INITCAP

语法:INITCAP(string)

功能:返回字符串的每个单词的第一个字母大写而单词中的其他字母小写的string。单词

是用.空格或给字母数字字符进行分隔。不是字母的

字符不变动c

使用位置:过程性语句和SQL语句。

4、LTRIM

语法:LTRIM(stringl,string2)

功能:返回删除从左边算起出现在string2中的字符的stringl。String2被缺省设立为单

个的空格。数据库将扫描stringl,从最左边开始。当

碰到不在string2中的第一个字符,结果就被返回了。LTRIM的行为方式与RTRIM很相似。

使用位置:过程性语句和SQL语句。

5、NLSINITCAP

语法:NLS」NITCAP(string[,nlspeirams])

功能:返回字符串每个单词第一个字母大写而单词中的其他字母小写的siring,nlsptrams

指定了不同于该会话缺省值的不同排序序列。假如不指定参数,则功能和IN1TCAP相同。N

Isparams可以使用的形式是:

<NLS_SORT=sort,

这里sort制订了一个语言排序序列。

使用位置:过程性语句和SQL语句。

6、NLS_LOWER

语法:NLSLOWER(string[,nlsparams])

功能:返回字符串中的所有字母都是小写形式的string。不是字母的字符不变。

Msparams参数的形式与用途和NLSINITCAP中的nlsparams参数是相同的。

假如nlsparams没有被包含,那么NLSLOWER所作的解决和

LOWER相同。

使用位置;过程性语句和SQL语句。

7、\LS_UPPER

语法:nlsnppnr(string[,nlsparams])

功能:返回字符串中的所有字母都是大写的形式的string。不是字母的字符不变。nlspara

ms参数的形式与用途和NLSINITCAP中的相同。假如

没有设定参数,则NLS-UPPER功能和UPPER相同。

使用位置:过程性语句和SQL语句。

8、REPLACE

语法:REPLACE(string,search_str[,replace_str])

功能:把string中的所有的子字符串search_str用可选的replace_str替换,假如没有指

定replace_str,所有的string中的子字符串

search_str都将被删除。REPLACE是TRANSLATE所提供的功能的一个子集。

使用位置:过程性语句和SQL语句。

9、RPAD

语法:RPAD(string),x[.string2])

功能:返I可在X字符长度的位置上插入一个string2中的字符的string1。假如string的

长度要比X字符少,就按照需要进行复制。假如string2

多于X字符,则仅stringl前面的X各字符被使用。假如没有指定string2,那么使用空格

进行填充。X是使用显示长度可以比字符串的实际长度

要长。RPAD的行为方式与LPAD很相似,除了它是在右边而不是在左边进行填充。

使用位置:过程性语句和SQL语句。

10、RTRIM

语法:RTRIM(stringl.[,string2])

功能:返回删除从右边算起出现在stringl中出现的字符string2.string2被缺省设立

为单个的空格.数据库将扫描stringl,从右边开始.当遇

到不在string2中的第一个字符,结果就被返回了RTRIM的行为方式与LTRIM很相似.

使用位置:过程性语句和SQL语句。

11、SOUNDEX

语法:SOUNDEX(strin?)

功能:返回string的声音表达形式.这对于比较两个拼写不同但是发音类似的单词而言

很有帮助.

使用位置:过程性语句和SQL语句。

12、SUBSTR

语法:SUBSTR(string:a[,b])

功能:返回从字母为值a开始b个字符长的string的一个子字符串.假如a是0,那么它

就被认为从第一个字符开始.假如是正数,返回字符是从左

边向右边进行计算的.假如b是负数,那么返I可的字符是从string的末尾开始从右向左进行

计算的.假如b不存在,那么它将缺省的设立为整个字符

串.假如b小于1,那么将返回NULL.假如a或b使用了浮点数,那么该数值将在解决进行以前

一方面被却为一个整数.

使用位置:过程性语句和SQL语句。

13、TRANSLATE

语法:TRANSLATE(string,fromstr,tostr)

功能:返回将所出现的from_str中的每个字符替换为to_str中的相应字符以后的

string.TRANSLATE是REPLACE所提供的功能的一个超集.

假如fromstr比to_str长,那么在from_str中而不在to_str中而外的字符将从string

中被删除,由于它们没有相应的替换字符.to_str不能为空

.Oracle把空字符串认为是NULL,并且假如TRANSLATE中的任何参数为NULL,那么结果也是N

ULL.

使用位置:过程性语句和SQL语句。

14、UPPER

语法:UPPER(string)

功能:返I口I大写的string.不是字母的字符不变.假如string是CHAR数据类型的,那么结果

也是CHAR类型的.假如string是VARCHAR2类型的,那么

结果也是VARCHAR2类型的.

使用位置:过程性语句和SQL语句。

字符函数一一返回数字

这些函数接受字符参数回数字结果.参数可以是CHAR或者是VARCHAR2类型的.尽管实际下许

多结果都是整数值,但是返回结果都是简朴的NUMBER

类型的,没有定义任何的精度或刻度范围.

16>ASCII

语法:ASCII(string)

功能:数据库字符集返回string的第一个字节的十进制表达.请注意该函数仍然称作为ASC

II.尽管许多字符集不是7位ASCII.CHR和ASCII是互为

相反的函数.CHR得到给定字符编码的响应字符.ASCII得到给定字符的字符编码.

使用位置:过程性语句和SQL语句。

]7、INSTR

语法:INSTR(stringl.string2[a,b])

功能:得到在stringl中包含string2的位置.stringl时从左边开始检查的,开始的位

置为a,假如a是一个负数,那么stringl是从右边开始进行

扫描的.第b次出现的位置将被返回.a和b都缺省设立为1,这将会返回在stringi中第一

次出现string2的位置.假如string2在a和b的规定下没有

找到,那么返回0.位置的计算是相对于stringl的开始位置的,不管a和b的取值是多少.

使用位置:过程性语句和SQL语句。

18、INSTRB

语法:INSTRB(stringl,string2[a,[b]])

功能:和INSTR相同,只是操作的对参数字符使用的位置的是字节.

使用位置:过程性语句和SQL语句。

19、LENGTH

语法:LENGTH(string)

功能:返回string的字节单位的长度.CHAR数值是填充空格类型的,假如string由数据

类型CHAR,它的结尾的空格都被计算到字符串长度中间.

假如string是NULL,返回结果是NULL,而不是0.

使用位置:过程性语句和SQL语句。

20、LENGTIIB

语法:LENGTHB(string)

功能:返回以字节为单位的string的长度.对于单字节字符集LENGTHB和LENGTH是同样

的.

使用位置:过程性语句和SQL语句。

21、NLSSORT

语法:NLSSORT(string[.nlsparams])

功能:得到用于排序string的字符串字节.所有的数值都被转换为字节字符串,这样在不同

数据库之间就保持了一致性.Nlsparams的作用和

NLS_INITCAP中的相同.假如忽略参数,会话使用缺省排序.

使用位置:过程性语句和SQL语句。

oracle存储过程的基本语法

工•基本结构

CREATEORREPLACEPROCEDURE存储过程名字

(

参数1INNUMBER,

参数2INNUMBER

)IS

变量1INTEGER:=0;

变量2DATE;

BEGIN

END存储过程名字

2.SELECTINTOSTATEMENT

将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条

记录,否则抛出异常(假如没有记录抛出NO_DATA_FOUND)

例子:

BEGIN

SELECTcollzcol2into变量1,变量2FROMtypcstructwherexxx;

EXCEPTION

WHENNO_DATA_FOUNDTHEN

xxxx;

END;

•••

3.IF判断

IFV_TEST=1THEN

BEGIN

dosomething

END;

ENDIF;

4.while循环

WHILEV_TEST=1LOOP

BEGIN

XXXX

END;

ENDLOOP;

5.变量赋值

V_TEST:=123;

6•用forin使用cursor

•••

IS

CURSORcurISSELECT*FROMxxx;

BEGIN

FORcur_resultincurLOOP

BEGIN

V_SUM:=cur_result.列名l+cur_result,列名2

END;

ENDLOOP;

END;

7.带参数的cursor

CURSORC_USER(C_IDNUMBER)ISSELECTNAMEFROMUSERWHERE

TYPEID=C_ID;

OPENC_USER(变量值);

LOOP

FETCHC_USERINTOV_NAME;

EXITFETCHC_USER%NOTFOUND;

dosomething

ENDLOOP;

CLOSEC_USER;

8•用pl/sqldeveloperdebug

连接数据库后建立一个TestWINDOW

在窗口输入调用SP的代码,F9开始debug,CTRL+N单步调试

关于oracle存储过程的若干问题备忘

1.在oracle中,数据表别名不能加as,如:

selecta.appnamefromappinfoa;—对的

selecta.appnamefromappinfoasa;—错误

也许,是怕和oracle中的存储过程中的关键字as冲突的问题吧

2.在存储过程中,select某一字段时,后而必须紧跟into,假如select整个记录,运用游标的

话就另当别论了。

selectaf.keynodeintoknfromAPPFOUNDATIONafwhereaf.appid=aidandaf.

foundationid=fid;—into,对的编译

selectaf.keynodefromAPPFOUNDATIONafwhereaf.appid=aidandaf.foundat

ionid=fid;—没有into,编译报错,提醒:Compilation

Error:PLS-00428:anINTOclauseisexpectedinthisSELECTstatement

3.在运用select…into…语法时,必须先保证数据库中有该条记录,否则会报出“nodata

found”异常。

可以在该语法之前,先运用selectcount(*)from查看数据库中是否存在该记录,假如存

在,再运用o...

4.在存储过程中,别名不能和字段名称相同,否则虽然编译可以通过,但在运营阶段会报错

selectkeynodeintoknfromAPPFOUNDATIONwhereappid=aidandfounda:ioni

d=fid;—对的运营

selectaf.keynodeintoknfromAPPFOUNDATIONafwhereaf.appid=appidandaf.f

oundationid=foundationid;—运营阶段报错,提醒

ORA01422:exactfetchreturnsmorethanrequestednumberofrows

5.在存储过程中,关于出现null的问题

假设有一个表A,定义如下:

createtableA(

idvarchar2(50)primarykeynotnull,

vcountnumber(8)notnull,

bidvarchar2(50)notnull—夕卜键

);

假如在存储过程中,使用如下语句:

selectsum(vcount)intofcountfromAwherebid='xxxxxx';

假如A表中不存在bid="xxxxxx”的记录,则fcount=null(即使fcount定义时设立了默认值,

如:fcountnumber(8):=0仍然无效,fcount还是会变成null),这样以后使用fcount时就

也许有问题,所以在这里最佳先判断一下:

iffcountisnullthen

fcount:=0;

endif;

这样就一切ok了。

6.Hibernate调用oracle存储过程

this.pnumberManager.getHibemateTemplate().execute(

CEnewHibernateCallback(){

publicObjectdoInHibernate(Sessicnsession)

throwsHibernateException,SQLException{

CallableStatementcs=session

.connection()

.prepareCall("{callmodifyapppnumber_remain(?)}");

cs.setString(lzfoundationid);

cs.execute();

returnnull;

});

oracle存储过程语法总结及练习

T.存储过程之if

clear;

createorreplaceproceduremydel(

in_aininteger)

as

begin

ifin_a<100then

dbmsoutput.put_line('小于100.*);

elsifin_a<200then

dbms_output.put_line(,大于100小于200.*);

else

dbms_output.put_lineC大于200.');

endif;

end;

/

setserveroutputon;

begin

mydel(1102);

end;

—2.存储过程之easel

clear;

createorreplaceproceduremydol(

in_aininteger)

as

begin

casein_a

when1then

dbms_output.put_line('小于100.');

when2then

dbms_output.put_line(,大于100小F200.');

else

dbms_output.put_line(,大于200.*);

enclcase;

end;

/

setserveroutputon;

begin

mydel(2);

end;

—1.存储过程之loopl

clear;

createorreplaceproceduremydel(

in_aininteger)

as

ainteger;

begin

a:=0;

loop

dbmsoutput.putline(a);

a:=a+l;

exitwhen

a>301;

endloop:

encl;

/

setserveroutputon;

begin

mydel(2);

end;

T.存储过程之loop2

clear;

createorreplaceproceduremydel(

in_aininteger)

as

ainteger;

begin

a:=0;

whilea<300loop

dbmsoutput.putline(a);

a:=a+l;

enclloop;

end;

setserveroutputon;

begin

mydel(2);

end;

一1.存储过程之loop3

clear;

createorreplaceproceduremydol(

in_aininteger)

as

ainteger;

begin

forain0..300

loop

dbms_output.put_line(a);

endloop;

encl;

setserveroutputon;

begin

mydel(2);

end;

/

clear;

selectename,cc:=(case

whencomm=nullthensal*12;

else(sal+comm)*12;

endcasefromemporderbysalpersal;

clear;

createorreplaceproceduregetstudentcomments(

istudontidinint,ocommcntsoutvarchar)

as

exams_satint;

avg_markint;

tmpcommentsvarchar(100);

begin

selectcount(examid)intoexams_satfromstudentexam

wherestudentid=istudentid;

ifexams_sat=0then

tmp_comments:=,n/a-thisstudentdidnotattendtheexam!);

else

selectavg(mark)intoavg_markfromstudentexam

wherestudentid=i_studentid;

case

whencivg_mark<50thentmp_comments:=,verybad';

whenavg_mark<60thentmp_comments:=,bad,;

whenavg_mark<70thentmp_commcnts:=,good,;

endcase;

endif;

ocommonts:=tmp_commonts;

end;

setserveroutputon;

declare

ppstudentexam,comments%type;

begin

getstudentconunents(8,pp);

dbms_output.put_line(pp);

encl;

deletefromempwhereempno<6000;

clear;

createorreplaceprocedureinsertdata(

in_numininteger)

as

myNumintdefault0;

empnoemp.empno%type:=1000;

begin

whilemyNurn<in_numloop

insertintoemp

values(empno,'hui?ImyNum,'coder,,7555,currentdate,8000,6258,30);

emp_no:=emp_no+l;

myNum:=myNum+l;

endloop:

encl;

/

setserveroutputon;

begin

insertdata(lO);

end;

select*fromemp;

clear;

selectstudentname,averageMark,case

whenaverageMark<60then'不及格'

whenaverageMark<70then'考得好'

whenaverageMark<80then'考得很好'

endcase

from(select(

selectb.namefromstudentbwhereb.studentid=a.studentid)asstudentname,

round(avg(mark),2)asaverageMarkfromstudentexamagroupbya.studentid);

ORACLE查询练习

emp员工表(empno员工号/ename员T姓名疗obI:作/mgr上级编号/hiredate受雇日期/sal薪金

/comm佣金/deptno部门编号)

dept部门表(deplno部门编号/dname部门名称/loc地点)

工资=薪金+佣金

1.列出至少有一个员工的所有部门。

2.列出薪金比“SMITH”多的所有员工。

3.列出所有员工的姓名及其直接.匕级的姓名。

4.列出受雇日期早于其直接上级的所有员工。

5.列出部门名称和这些苗门的员工信息,同时列出那些没有员工的部门

6.列出所有“CLERK”(办事员)的姓名及其部门名称。

7.列出最低薪金大于1500的各种工作。

8.列出在部门“SALES”(销售部)工作的员工的姓名,假定不知道销售部的部门编号。

9.列出薪金高于公司平均薪金的所有员工。

10.列出与“SCOTT”从事相同工作的所有员工。

11.列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金。

12.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。

13.列出在每个部门工作为员工数量、平均工资和平均服务期限。

14.列出所有员工的姓名、部门名称和工资。

15.列出所有部门的具体信息和部门人数。

16.列出各种工作的最低工资。

17.列出各个部门的MANAGER(经理)的最低薪金。

18.列出所有员工的年工资,按年薪从低到高排序。

...........1..............

selectdnamefromdeptwheredeptnoin(

selectdeptnofromemp);

--------2----------

select*fromempwheresal>(

selectsalfromempwhereename='SMITH');

--------3..............

selecta.ename.(

selectenamefromempbwhereb.empno=a.mgr)asbossnaniefromempa;

--------4----------

selecta.enamefromempawherea.hiredate<(

selecthiredatefromempbwhereb.empno=a.mgr);

...........5..............

selecta.dname,b.einpno,b.ename,b.job,b.mgr,b.hireda(e,b.sal,m,b.dep(no

fromdeptaleftjoinempbona.deptno=b.deptno;

6----------

selecta.ename,b.dnamefromempajoindeptb

ona.deptno=b.deptnoandajob-CLERK';

--------7----------

selectdistinctjobasHighSalJobfromempgroupbyjobhavingmin(sal)>1500;

--------8----------

selectenarnefromempwheredeptno=(

selectdeptnofromdeptwherednamc:'SALES');

9

selectenamefromempwheresal>(

selectavg(sal)fromemp);

...........10.............

selectenaniefromempwherejob=(

selectjobfromempwhereename='SCOTT');

--------11----------

selecta.ename,a.salfromempawherea.salin(

selectb.salfromempbwhereb.deptno=30)anda.deptno<>30;

--------12----------

selectename,salfromempwheresal>(

selectmax(sal)fromempwheredcptno=30);

--------13----------

select

(selectb.dnamefromdeptbwherea.deptno=b.dcptno)asdeptname,

count(deptno)asdeptcount,

avg(sal)asdeptavgsal

fromempagroupbydeptno;

--------14----------

select

a.ename,

(selectb.dnamcfromdeptbwhereb.dcptno=a.dcptno)asdeptname,

sal

fromempa;

...........15.............

select

a.deplno,

a.dname,

a.loc,

(selectcount(deptno)fromempbwhereb.deptno=a.deptnogroupbyb.deptno)asdeplcount

fromdepta;

--------16----------

selectjob,avg(sal)fromempgroupbyjob;

--------17----------

selectdeptno,niin(sal)fromempwherejob='MANAGER'groupbydeptno;

18

selectename.(sal+nvl(comin,0))*12assalpersalfromemporderbysalpersal;

ORACLE子句查询,分组等

A.同表子查询作为条件

a.给出人口多于Russia(俄国)的国家名称SELECTnameFROMbbc

WHEREpopulation>

(SELECTpopulationFROMbbc

WHEREname='Russia')

b.给出'India'(印度),'Iran’(伊朗)所在地区的所有国家的所有信息SELECT*FROMbbc

WHEREregionIN

(SELECTregionFROMbbc

WHEREnameIN('India'Iran'))

c.给出人均GDP超过'UnitedKingdom'(英国)的欧洲国家.SELECTnameFROMbbc

WHEREregion=,Europe5ANDgdp/population>

(SELECTgdp/populalionFROMbbc

WHEREname=,UnitedKingdom')

d.这个查询事实上等同于以下这个:

selectel.enamefromempel,(selectempnofromempwhereename='KING')e2whe

reel.mgr=e2.empno;

你可以用EXISTS写同样的查询,你只要把外部查询一栏移到一个像下面这样的子查询环境

中就可以了:

selectenamefromempe

whereexists(select0fromempwheree.mgr=empnoandename='KING');

当你在一个WHERE子句中写EXISTS时,又等于向最优化传达了这样一条信息,即你想让外

部杳询先运营,使用每一个值来从内部查询(假定:EXISTS=由外而内)中得到一个值。

B.异表子查询作为条件

a.select*fromstudentExamwherestudentid=(selectstudentidfromstudentwhe

rename-吴丽丽');

b.select*fromstudentexcimwherestudentidin(

selectstudentidfromstudent)orderbystudentid;

c.select*fromstudentwherestudentidin(selectstudentidfromstudentexamw

heremark>80);

3.selectstudentexam.mark,studentexam.studentidasseid,student,studentid,stud

ent.namefromstudentexam,studentwherestudent.studentid=studentexam.studentid;

过滤分组:

顺序为先分组,再过滤,最后进行记录(实际值).

selectstudentid,count(*)ashighpassesfromstudentexamwheremark>70groupbys

tudentid;

假使我们不想通过数据表中的实际值,而是通过聚合函数的结果来过过滤查询的结果.

selectstudentid,avg(mark)asaveragemarkfromstudentexamwhereavg(mark)<50or

avg(mark)>70groupbystudentid;(此句错误,where句子是不能用聚合函数作条件的)此

时要用having.

selectstudentid,avg(mark)fromstudentexamgroupbystudentidhavingavg(nar

k)>70oravg(mark)<50;

selectstudentid,avg(mark)fromstudentexamwherestudentidin(l,7,9,5)groupby

studentidhavingavg(mark)〉70;(先分组,再过滤,再having聚合,最后再记录).

selectstudentid,avg(mark)asaveragemarkfromstudentexamwhereexamidin(5,8,1

1)groupbystudentidhavingavg(mark)<50oravg(mark)>70;

返回限定行数查询:

selectnamefromstudentwhererownum<=10;

oracle中使用rownum关健字指定,但该关键字必须在where子句中与一个比较运算符一起

指定,而不能与orderby一起配合便用,由于rownum维护的是原始行号.假如需要用group

by\orderby就用子句查询作表使用的方法:

selectstudentid,averagemarkfrom(selectstudentid,avg(mark)asaveragemarkfrom

studentexamgroupbystudentidorderbyaveragemarkdesc)whererownum<=10;

oracle存储过程语法:Oracle存储过程入门学习基本语法

1.基本结构

createORREPLACEPROCEDURE存储过程名字

(

参数1INNUMBER,

参数2INNUMBER

)IS

变量1INTEGER:=0;

变量2DATE;

BEGIN

END存储过程名字

2.selectINTOSTATEMENT

将select查询的结果存入到变量中,可以同时将多个列存储多个变量中,必须有一条记录,否则抛出

异常(假如没有记录抛出NO_DATA_FOUND)

例子:

BEGIN

selectcol1,col2into变量1,变量2FROMtypestructwherexxx;

EXCEPTION

WHENNO_DATA_FOUNDTHEN

xxxx;

END;

3.IF判断

IFV_TEST=1THEN

BEGIN

dosomething

END;

ENDIF;

4.while循环

WHILEV_TEST=1LOOP

BEGIN

XXXX

END;

ENDLOOP;

5.变量赋值

V_TEST:=123;

6.用forin使用cursor

IS

CURSORcurISselect*FROMxxx;

BEGIN

FORcur_resultincurLOOP

BEGIN

V_SUM:=cur_result.歹ij名1+cur_result.歹U名2

END;

ENDLOOP;

END;

7.带参数的cursor

CURSORC_USER(C_IDNUMBER)ISselectNAMEFROMUSERwhereTYPEID=C_ID;

OPENC_USER(变量值);

LOOP

FETCHC_USERINTOV_NAME;

EXITFETCHC_USER%NOTFOUND;

dosomething

ENDLOOP;

CLOSEC_USER;

8.用pl/sqldeveloperdebug

连接数据库后建立一个TestWINDOW

在窗口输入调用SP的代码,F9开始debug,CTRL+N单步调试

oracle语法:Oracle触发器语法及实例基础知识(一)

-Oracle触发帝语法

触发器是特定事件出现的时候,自动执行的代码块I___I类似于存储过程,触发器和存储过程的区别

在于:存储过程是由用户或应用程序显式调用的,而触发器是不能被直接调用的

功能:

1、允许/限制对表的修改

2、自动生成派生列,比如自增字段

3、强制数据一致性

4、提供审计和口记记录

5、防止无效的事务解决

6、启用复杂的业务逻辑

触发器触发时间有两种:after和befor回

1、触发器的语法:

CREATE[ORREPLACE]TIGGER触发器名触发时间触发事件

ON表名

[FOREACHROW]

BEGIN

pl/sql语句

END

其中:

由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途

触发时间:指明触发器何小:执行,该值可取:

before…表达在数据库动作的前触发器执行;

after…表达在数据库动作的后出发器执行

触发事件:指明哪些数据库动作会触发此触发器:

insert:数据库插入会触发此触发器;

update:数据库修改会触发此触发器;

delete:数据库删除会触发此触发器回

foreachrow:对表的每■•行触发器执行一次假如没有这一选项,则只对整个表执行一次

2、举例:

下面的触发器在更新表auths的前触发,目的是不允许在周末修改表:

createtriggerauth_securebeforeinsertorupdateordelete〃对整表更新前触发

onauths

begin

if(to_char(sysdate,'DY')=SUN'

RAISE_APPLIC/mON_ERROR(・20600;不能在周末修改表auths);

endif;

end

例子:

CREATEORREPLACETRIGGERCRM.TSUBUSERINFOAURNAMEAFTERUPDATEOF

STAFF_NAME

ONCRM.T_SUB_USERINFO

REFERENCINGOLDASOLDNEWASNEW

FOREACHROW

declare

begin

if:NEW.STAFF_NAME!=:OLD.STAFF_NAMEthen

begin

客户投诉

updateT_COMPLAINT_MANAGEsetSERVE_NAME=:NEW.STAFFNAMEwhere

SERVE_SEED=:OLD.SEED;

客户关怀

updateT_CUSTOMER_CAREsetEXECUTOR_NAME=:NEW.STAFF_NAME

whereEXECUTOR_SEED=:OLD.SEED;

客户服务

updateT_CUSTOMER_SERVICEsetEXECUTOR_NAME=:NE^.STAFF_NAME

whereEXECUTORSEED=:OLD.SEED:

end;

endif;

endT_sub_userinfo_aur_name;

2Oracle触发器详解

开始:

createtriggerbiufer_employees_department_id

beforeinsertorupdateofdepartmentjdonemployees

referencingoldasold_valienewasnewvalue

foreachrow

when(new_value.departnent_id<>80)

begin

:new_missionj>ct:=0;

end;

1、触发器的组成部分:

1、触发据名称

2、触发语句

3、触发器限制

4、触发操作

1.1、触发器名称

createtriggerbiufer_employees_department_id

命名习惯:

biufer(beforeinsertupdateforeachrow)

employees表名

departmentid歹ij名

1.2.触发语句

比如:

表或视图上的DML语句

DDL语句

数据库关闭或启动,startupshutdown等等

beforeinsertorupdate

ofdepartment_id

onemployees

referencingoldasold_value

newasnew_value

foreachrow

介绍说明:

1、无论是否规定了departmentjd,对employees表进行insert的时候

2、对employees表的departmentjd列进行update的时候

1.3、触发器限制

when(new_value.departmenl_id<>80)

限制不是必须的回I此例表达假如列departmentjd不等于80的时候,触发器就会执行

其中的new_value是代表更新的后的值回

1.4、触发操作

是触发器的主体

begin

:new_mission_pct:=0;

end;

主体很简朴,就是将更新后的commission_pct列置为0

触发:

insertintoemployees(employeeid,last_name,firsLname,hiredate,jobjd,email,

department_id,salary,conmission_pct)

values(12345,'Chen','Donny*,sysdate,12,".eo,10000,.25);

selectcommission_pctfromemployeeswhereemployee_id=12345;

2、触发器的类型有:

触发器类型:

1、语句触发器

2、行触发器

3、INSTEADOF触发

4、系统条件触发器

5、用户事件触发器

2.1、语句级触发器.(语句级触发器对每个DML语句执行一次)

是在表上或者某些情况下的视图上执行的特定语句或者语句组上的触发器叵1可以和INSERT.

UPDATE.DELETE或者组合上进行关联I___I但是无论使用什么样的组合,各个语句触发器都只会针时

比如,无论update多少行,也只会调用一次update语句触发器回

指定语句激活一次

例子:

createorreplacetriggertri_test

afterinsertorupdateordelete_disibledevent=>

测试,插入几条记录

insertintotestvalues(O.'ff');

insertintotestvalues(O,'ff');

insertintotestvalues(O,'tt');

例子2:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论