-
rowcount不是指一共多少行
查看全部 -
接受鍵盤輸入
accept num prompt ' ****提示****‘;
num是地址值
查看全部 -
DECLARE CURSOR CUR IS SELECT A.EMPNO,A.ENAME FROM SCOTT.EMP A;
? ? ? ? V_EMPNO SCOTT.EMP.EMPNO%TYPE;
? ? ? ? V_ENAME SCOTT.EMP.ENAME%TYPE;
BEGIN
? ? ? ? --打開游標(biāo)
? ? ? ? OPEN CUR;
? ? ? ? --判斷是否打開
? ? ? ? IF CUR%ISOPEN THEN?
? ? ? ? LOOP
? ? ? ? ? --當(dāng)無數(shù)據(jù)時(shí),退出循環(huán)
? ? ? ? ? EXIT WHEN CUR%NOTFOUND;
? ? ? ? ? FETCH CUR INTO V_EMPNO,V_ENAME;
? ? ? ? ? DBMS_OUTPUT.put_line(V_EMPNO||':'||V_ENAME);? ? ??
? ??
? ? ? ? END LOOP;
? ? ? ? --關(guān)閉游標(biāo)
? ? ? ? CLOSE CUR;
? ? ? ? END IF;
END;? ??
查看全部 -
-------------------PL/SQL程序設(shè)計(jì)方法-------------------
--瀑布模型
/*
1.需求分析
2.設(shè)計(jì)
? 1)概要設(shè)計(jì)
? 2)詳細(xì)設(shè)計(jì)
3.編碼 (Coding)
4.測試(Testing)
5.上線
SQL語句
變量:
? ? 1.初始值是多少
? ? 2.最終值如何得到
*/
------案例1、統(tǒng)計(jì)每年入職的員工人數(shù)-----
--SQL語句
select to_char(hiredate,'yyyy') from emp;
--> 游標(biāo) --> 循環(huán) --> 退出條件:notfound
/*
變量:1.初始值? ? 2.如何得到
每年入職的員工人數(shù):
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
set serveroutput on;
declare
? ? cursor cemp is select to_char(hiredate,'yyyy') from emp; --定義游標(biāo),從表中取出員工入職年份
? ? phiredate varchar2(4);?
? ? --每年入職的員工人數(shù):
? ? count80 number := 0;
? ? count81 number := 0;
? ? count82 number := 0;
? ? count87 number := 0;
begin
? ? open cemp;
? ? loop?
? ? ? fetch cemp into phiredate; --取出一個(gè)員工的入職年份
? ? ? exit when cemp%notfound; --取不到退出
? ? ? --判斷入職年份
? ? ? if phiredate = '1980' then count80 := count80 + 1;
? ? ? ? ?elsif phiredate = '1981' then count81 := count81 +1;
? ? ? ? ?elsif phiredate = '1982' then count82 := count82 +1;
? ? ? ? ?else count87 := count87 + 1;
? ? ? ?end if;
? ? end loop;
? ? close cemp;?
? ? --輸出結(jié)果
? ? dbms_output.put_line('Total:'||(count80 + count81 + count82 + count87));
? ? dbms_output.put_line('1980:'||count80);
? ? dbms_output.put_line('1981:'||count81);
? ? dbms_output.put_line('1982:'||count82);
? ? dbms_output.put_line('1987:'||count87);
end;
/
/*
---案例2、為員工漲工資。從最低工資漲起,每人漲10%,單工資總額不能超過5萬元,請計(jì)算漲工資的人數(shù)和漲工資后的工資總額,并輸出漲工資人數(shù)及工資總額。
SQL語句
select empno,sal from emp order by sal;
-- > 游標(biāo) --> 循環(huán) --> 退出條件: 1.工資總額>5w? 2.%notfound
變量:1.初始值? ? 2.如何得到
漲工資的人數(shù): countEmp number := 0;
漲后的工資總額:salTotal number;
? ?1.select sum(sal) into salTotal from emp;
? ?2.漲后的工資總額=漲前的工資總額? + sal * 0.1
*/
set serveroutput on;
declare
? ? cursor cemp is select empno,sal from emp order by sal; --定義游標(biāo)
? ? pempno emp.empno%type; --定義員工編號變量
? ? psal? ? ? ? emp.sal%type; --定義員工工資變量
? ? countEmp number := 0; --漲工資人數(shù)計(jì)數(shù)器
? ? salTotal number; --漲后的工資
begin
? ? select sum(sal) into salTotal from emp; --給合計(jì)工資賦值
? ? open cemp;?
? ? loop
? ? ? exit when salTotal >50000; --合計(jì)工資大于5w退出循環(huán)
? ? ? fetch cemp into pempno,psal; --從游標(biāo)取值賦值到變量
? ? ? exit when cemp%notfound; --取不到值退出循環(huán)
? ? ? if? salTotal + psal * 0.1 <= 50000 then --漲后的工資小于5w才執(zhí)行漲工資
? ? ? update emp set sal = sal * 1.1 where emp.empno = pempno; --執(zhí)行漲工資
? ? ??
? ? ? countEmp := countEmp + 1; --統(tǒng)計(jì)張工資的人數(shù)
? ? ? salTotal := salTotal + psal * 0.1; --漲后的工資總額
? ? ??
? ? ? end if;
? ? ??
? ? ?end loop;
? ? close cemp;
? ??
? ? --commit; 提交最終漲工資事務(wù)
? ? dbms_output.put_line('漲工資的人數(shù)為:'||countEmp);
? ? dbms_output.put_line('漲工資后的工資總額為:'||salTotal);
? ??
end;
/
/*
案例3、用PL/SQL語言編寫程序,實(shí)現(xiàn)按部門分段(6000以上、(6000、3000)3000以下)統(tǒng)計(jì)各工資段的職工人數(shù)、以及各部門的工資總額(工資總額中不包括獎(jiǎng)金)
SQL語句
1.有哪些部門
? ? select deptno from dept; --游標(biāo) --> 循環(huán) --> 退出條件:notfound
2.部門中員工的薪水
? ? select sal from emp where deptno = ? 帶一個(gè)參數(shù)的游標(biāo) --> 循環(huán) --> 退出條件:notfound
? ??
變量:1.初始值? ? ? ?2.如何得到
每個(gè)段的員工人數(shù):
count1 number;
count2 number;
count3 number;
每個(gè)部門的工資總額: 有2中方式獲取
saltotal number;
1.select sum(sal) into saltotal from emp where deptno = ???
2.累加
*/
--創(chuàng)建一張表保存各工資段數(shù)據(jù)
create table msg(
? ? ? ?deptno number,
? ? ? ?count1 number,
? ? ? ?count2 number,
? ? ? ?count3 number,
? ? ? ?saltotal number);
? ? ? ?
SELECT * FROM msg;
--程序第一種實(shí)現(xiàn)方式,SQL統(tǒng)計(jì)
DECLARE
? CURSOR cdept IS SELECT deptno FROM dept; --定義游標(biāo),取出部門
? pdeptno dept.deptno%TYPE; --定義部門變量
? CURSOR cemp(dno NUMBER) IS SELECT sal FROM emp WHERE deptno = pdeptno; --部門中員工的薪水
? psal emp.sal%TYPE; --員工薪水
? --每個(gè)段的員工人數(shù)
? count1 NUMBER;
? count2 NUMBER;
? count3 NUMBER;
? --每個(gè)部門的工資總額
? saltotal NUMBER;
BEGIN
? OPEN cdept; --打開部門游標(biāo)
? LOOP
? ? --取出一個(gè)部門
? ? FETCH cdept INTO pdeptno;
? ? EXIT WHEN cdept%NOTFOUND;
??
? ? --初始化的工作
? ? count1 := 0;
? ? count2 := 0;
? ? count3 := 0;
? ? --得到部門的工資總額
? ? SELECT SUM(sal) INTO saltotal FROM emp WHERE deptno = pdeptno;
??
? ? --取部門中員工的薪水
? ? OPEN cemp(pdeptno); --打開員工游標(biāo)
? ? LOOP
? ? ? FETCH cemp? INTO psal;
? ? ? EXIT WHEN cemp%NOTFOUND;
? ? ? IF psal < 3000 THEN count1 := count1 + 1;
? ? ? ELSIF psal >= 3000 AND psal < 6000 THEN count2 := count2 + 1;
? ? ? ELSE count3 := count3 + 1;
? ? ? END IF;
? ??
? ? END LOOP;
? ? CLOSE cemp; --關(guān)閉員工游標(biāo)
? ??
? ? INSERT INTO msg VALUES (pdeptno, count1, count2, count3, nvl(saltotal,'0'));
? ??
? END LOOP;
? CLOSE cdept; --關(guān)閉部門游標(biāo)
? --COMMIT;
? dbms_output.put_line('統(tǒng)計(jì)完成');
END;
/
--程序第二種實(shí)現(xiàn)方式,算數(shù)累加
DECLARE
? CURSOR cdept IS SELECT deptno FROM dept; --定義游標(biāo),取出部門
? pdeptno dept.deptno%TYPE; --定義部門變量
? CURSOR cemp(dno NUMBER) IS SELECT sal FROM emp WHERE deptno = pdeptno; --部門中員工的薪水
? psal emp.sal%TYPE; --員工薪水
? --每個(gè)段的員工人數(shù)
? count1 NUMBER;
? count2 NUMBER;
? count3 NUMBER;
? --每個(gè)部門的工資總額
? saltotal NUMBER;
BEGIN
? OPEN cdept; --打開部門游標(biāo)
? LOOP
? ? --取出一個(gè)部門
? ? FETCH cdept INTO pdeptno;
? ? EXIT WHEN cdept%NOTFOUND;
??
? ? --初始化的工作
? ? count1 := 0;
? ? count2 := 0;
? ? count3 := 0;
? ? saltotal := 0;
? ??
? ? --取部門中員工的薪水
? ? OPEN cemp(pdeptno); --打開員工游標(biāo)
? ? LOOP
? ? ? FETCH cemp? INTO psal;
? ? ? EXIT WHEN cemp%NOTFOUND;
? ? ? saltotal := saltotal + psal;
? ? ? IF psal < 3000 THEN count1 := count1 + 1;
? ? ? ELSIF psal >= 3000 AND psal < 6000 THEN count2 := count2 + 1;
? ? ? ELSE count3 := count3 + 1;
? ? ? END IF;
? ??
? ? END LOOP;
? ? CLOSE cemp; --關(guān)閉員工游標(biāo)
? ??
? ? INSERT INTO msg VALUES (pdeptno, count1, count2, count3, nvl(saltotal,'0'));
? ??
? END LOOP;
? CLOSE cdept; --關(guān)閉部門游標(biāo)
? COMMIT;
? dbms_output.put_line('統(tǒng)計(jì)完成');
END;
/
SELECT * FROM msg;
/*
案例3、用plsql語言編寫一個(gè)程序。按系(系名)分段統(tǒng)計(jì)(成績小于60分,60-85分,85分以上)“大學(xué)物理”課程各分?jǐn)?shù)段的學(xué)生人數(shù),及各系學(xué)生的平均成績。
1.SQL.語句
? ? ? ?1).得到有哪些系
? ? ? ? ? ? ? select dno,dname from dep;? --> 游標(biāo) -- 循環(huán) --> 退出條件:notfound
? ? ? ?2).得到系中,選修了“大學(xué)物理”課程學(xué)生的成績
? ? ? ? ? ? ? select grade from sc where cno = (select cno from course where cname = ???)
? ? ? ? ? ? ? ? ?and sno in (select sno from student where dno = ???);
? ? ? ? ? ? ? ? ? --> 帶參數(shù)的光標(biāo) --> 循環(huán) --> 退出條件:notfound
2.變量:1).初始值? ? ? 2).如何得到
? ? ? ?count1 number;? ?count2 number;? ?count3 number;? ? 每個(gè)分?jǐn)?shù)段的人數(shù)
? ? ? ?avggrade number;? ? ? ? 每個(gè)系選修了“大學(xué)物理”學(xué)生平均成績
? ? ? ? ? ? ? ? 1.算術(shù)運(yùn)算
? ? ? ? ? ? ? ? 2.select avg(grade) into avggrade from sc where cno = (select cno from course where cname=???)
? ? ? ? ? ? ? ? ? ? ? and sno in (select? sno from student? where? dno = ???);
*/
--創(chuàng)建一個(gè)表存儲(chǔ)結(jié)果
CREATE TABLE msg1(
? ? ? ?coursename? ?VARCHAR2(20),
? ? ? ?dnma? ? ? ? ? ? ?VARCHAR2(20),
? ? ? ?count1? ? ? ? ? ?NUMBER,
? ? ? ?count2? ? ? ? ? ?NUMBER,
? ? ? ?count3? ? ? ? ? ?NUMBER,
? ? ? ?avggrade? ? ? ? NUMBER
);
--程序
SET serveroutput ON;
DECLARE
? ? --定義系的游標(biāo)
? ? CURSOR cdept IS select dno,dname from dep;
? ? pdno dep.dno%TYPE;??
? ? pdname dep.dname%TYPE;
? ??
? ? --定義成績游標(biāo)
? ? CURSOR cgrade(coursename VARCHAR2, depno NUMBER)
? ? ? ? ? ? IS select grade? from sc where cno = (select cno from course where cname=coursename)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? and sno in (select? sno from student? where? dno = depno);
? ? pgrade sc.grade%TYPE;
? ??
? ? count1 number;? ?count2 number;? ?count3 number;? ? --每個(gè)分?jǐn)?shù)段的人數(shù)
? ? avggrade NUMBER;? ? ? ? --每個(gè)系選修了“大學(xué)物理”學(xué)生平均成績
? ?
? ? pcourseName VARCHAR2(20) := '大學(xué)物理';? --課程名稱
?
BEGIN
? ? OPEN cdept; --打開系的游標(biāo)
? ? LOOP
? ? ? ? ?--取出一個(gè)系的信息
? ? ? ? ?FETCH cdept INTO pdno,pdname;
? ? ? ? ?EXIT WHEN cdept%NOTFOUND;
? ? ? ? ?
? ? ? ? ?count1 := 0; count2 := 0; count3 := 0;? ?--初始值
? ? ? ? ?
? ? ? ? ?--系的平均成績
? ? ? ? ?select avg(grade) into avggrade from sc where cno = (select cno from course where cname=pcourseName)
? ? ? ? ? ? ? ? ? ? ? and sno in (select? sno from student? where? dno = pdno);
? ? ? ? ??
? ? ? ? ?--取出系中,選修了大學(xué)物理的學(xué)生成績
? ? ? ? ?OPEN cgrade (pcourseName,pdno);
? ? ? ? ?LOOP
? ? ? ? ? ? ? --取出一個(gè)學(xué)生的成績
? ? ? ? ? ? ? FETCH cgrade INTO pgrade;
? ? ? ? ? ? ? EXIT WHEN cgrade%NOTFOUND;
? ? ? ? ? ? ??
? ? ? ? ? ? ? --判斷成績范圍
? ? ? ? ? ? ? ? ? ?IF pgrade < 60 THEN count1 := count1 + 1;
? ? ? ? ? ? ? ? ? ?ELSIF pgrade >= 60 AND pgrade < 85 THEN count2 := COUNT2 + 1;
? ? ? ? ? ? ? ? ? ?ELSE count3 := count3 + 1;
? ? ? ? ? ? ? ? ? ?END IF;
? ? ? ? ?
? ? ? ? ?END LOOP;
? ? ? ? ?
? ? ? ? ?CLOSE cgrade;
? ? ? ? ?
? ? ? ? ?--保存當(dāng)前的結(jié)果
? ? ? ? ?INSERT INTO msg1 VALUES(pcourseName,pdname,count1,count2,count3,avggrade);
? ? ? ? ?
? ? END LOOP;
? ? CLOSE cdept;
? ? --COMMIT;
? ? dbms_output.put_line('統(tǒng)計(jì)完成');
END;
/
SELECT * FROM msg1;
查看全部 -
if---then
elsif then
esle;
while---loop
end--loop;
exit while---loop
end loop;
for?變量名?in? 1..10 loop
end loop;
查看全部 -
set serveroutput on
declare
cursor cm1 is select to_char(e.hiredate,'yyyy')? from emp e;
pdate VARCHAR2(4);
count80 number:=0;
count81 number:=0;
count82 number:=0;
begin
open cm1;
loop
fetch cm1 into pdate;
exit when cm1%notfound;
if pdate='1980' then count80:=count80+1;
elsif pdate='1981' then count81:=count81+1;
elsif pdate='1982' then count82:=count82+1;
else count82:=count82+1;
end if;
end loop;
close cm1;
dbms_output.put_line('總共入職:'||(count80+count81+count82));
dbms_output.put_line('1980年入職:'||count80);
end;
/查看全部 -
例外是程序設(shè)計(jì)語言提供一種功能,用來增強(qiáng)程序的健壯性和容錯(cuò)性
系統(tǒng)例外
no_data_found??? 沒有找到數(shù)據(jù)
too_many_rows ?? select..into語句匹配多個(gè)行
Zero_Divide???? 被零除
Value_error????? 算數(shù)或轉(zhuǎn)換錯(cuò)誤
timeout_on_resource? 在等待資源時(shí)發(fā)生超時(shí)
查看全部 -
1、光標(biāo)的屬性
%found %notfound
%isopen 判斷光標(biāo)是否打開
%rowcount 影響的行數(shù)
2、光標(biāo)的限制:默認(rèn)情況下,oracle數(shù)據(jù)庫只允許在同一個(gè)會(huì)話中,打開300個(gè)光標(biāo)
查看全部 -
光標(biāo)語法
cursor 光標(biāo)名 【(參數(shù)名 數(shù)據(jù)類型【,參數(shù)名 數(shù)據(jù)類型】...)】
is select 語句;
打開光標(biāo)
open c1;? (打開光標(biāo)執(zhí)行查詢)
關(guān)閉光標(biāo)
close c1; (關(guān)閉游標(biāo)釋放資源)
--取一行光標(biāo)的值
fetch c1 into pename;(取一行到變量中)
查看全部 -
while 循環(huán)
while total <=2500 loop
....
end loop;
loop循環(huán)
looP
exit [when 條件];
....
end loop;
for循環(huán)
for i in 1..3 loop
....
end loop;
查看全部 -
if語句
1.if 條件 then 語句1;
語句2;
end if;
2. if 條件 then 語句序列 1;
esle 語句序列2;
end if;
3. if 條件 then 語句;
eslif 語句 then 語句;
else 語句;
end if;
/*
判斷用戶從鍵盤輸入的數(shù)字
如何使用if語句
接收一個(gè)鍵盤輸入(從鍵盤輸?shù)亩际亲址?br />*/
set serveroutput onaccept num prompt'請輸入一個(gè)數(shù)字';
declare
pnum number = #
begin
if pnum=0 then
dbms_output.put_line('輸入的數(shù)字為0');
elsif pnum =1
dbms_output.put_line('輸入數(shù)字為1');
else dbms_output.put_line('輸入的是其他數(shù)字');
end if;
end;
/
查看全部 -
:= 賦值查看全部
-
記錄型變量 代表表中的一行(多個(gè)列),類似數(shù)組
emp_rec.列名 := ‘xxx’ --引用某一列的數(shù)據(jù) ?
查看全部 -
說明部分,變量定義,對變量賦值注意是 冒號+等號 進(jìn)行賦值
查看全部 -
pl/sql程序結(jié)構(gòu)
declare 說明部分,變量說明、光標(biāo)申明、例外說明
begin開始(語句序列-dml語句) end+分號結(jié)尾 最后‘/’,中間exception(例外處理語句)
查看全部
舉報(bào)