版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 项目部零星费用登记表
- 生活护理与康复训练结合
- 精-品解析:2024年北师大版七年级数学下册期末测试(原卷版)
- 山东省东营市2026届高三下学期第五次调研考试语文试题含解析
- 【2026年】信息主管面试题(某大型央企)试题集详解
- 【2026】(中小学教师类D类)事业单位考试综合应用能力江西省南昌市复习要点精析
- 26年老年低体温应急流程课件
- 【2025】哈尔滨市双城区承恩街道工作人员招聘考试真题
- 医学26年:肾内科人才培养要点 查房课件
- 26年银发头痛应急处理实操课件
- 《GMP认证培训资料》课件
- 《船舶信号系统实训》课件-5.4主机车钟系统功能与操作
- 家族族谱模板
- 申报专业答辩
- QB/T 6019-2023 制浆造纸专业设备安装工程施工质量验收规范 (正式版)
- (正式版)QBT 2570-2024 贴标机
- 分式方程第2课时课件北师大版八年级数学下册
- 招投标专项检查报告
- 高速铁路桥隧建筑物病害及状态等级评定 涵洞劣化项目及等级
- 安徽省定远县公开选调教师(第二批)和教研员笔试历年高频考点试题含答案带详解
- 小针刀治疗腱鞘炎-课件
评论
0/150
提交评论