oracle第三天

來源:互聯網
上載者:User

標籤:

HelloWorld.sql

set serveroutput on

declare
--說明部分
begin
--程式
dbms_output.put_line(‘Hello World‘);
end;
/

if語句.sql

--判斷使用者輸入的數字

set serveroutput on

--接收鍵盤輸入
--num: 地址值,在該地址上,存了輸入的值
accept num prompt ‘請輸入一個數字‘;

declare
--定義變數儲存輸入的數字
--隱式轉換
pnum number := #
begin

if pnum = 0 then dbms_output.put_line(‘您輸入的是0‘);
elsif pnum = 1 then dbms_output.put_line(‘您輸入的是1‘);
elsif pnum = 2 then dbms_output.put_line(‘您輸入的是2‘);
else dbms_output.put_line(‘其他數字‘);
end if;
end;
/

帶參數的游標.sql

--查詢某個部門中員工的姓名

set serveroutput on

declare
--帶參數的游標
cursor cemp(dno number) is select ename from emp where deptno=dno;
pename emp.ename%type;
begin
open cemp(20);
loop
fetch cemp into pename;
exit when cemp%notfound;

dbms_output.put_line(pename);

end loop;
close cemp;
end;
/

給員工漲工資.sql

--漲工資 總裁1000 經理800 其他400

set serveroutput on

declare
cursor cemp is select empno,empjob from emp;
pempno emp.empno%type;
pjob emp.empjob%type;
begin
rollback;

open cemp;
loop
--取一個員工 漲工資
fetch cemp into pempno,pjob;
exit when cemp%notfound;

--判斷職位
if pjob = ‘PRESIDENT‘ then update emp set sal=sal+1000 where empno=pempno;
elsif pjob = ‘MANAGER‘ then update emp set sal=sal+800 where empno=pempno;
else update emp set sal=sal+400 where empno=pempno;
end if;

end loop;

close cemp;

--事務的隔離等級
commit;

dbms_output.put_line(‘漲工資完成‘);
end;
/

 游標

 

--使用遊標查詢員工姓名和工資,並列印

/*
1. 游標的屬性
%isopen: 是否開啟
%rowcount: 行數
%notfound: 沒有記錄

2. 預設允許一次開啟300個游標(修改游標: 第四天 管理方案)
SQL> show parameters cursor

NAME TYPE VALUE
------------------------------------ ----------- -------
cursor_sharing string EXACT
cursor_space_for_time boolean FALSE
open_cursors integer 300
session_cached_cursors integer 20
*/

set serveroutput on

declare
--定義游標代表員工集合
cursor cemp is select ename,sal from emp;
pename emp.ename%type;
psal emp.sal%type;
begin
open cemp;

loop
--取一個員工
fetch cemp into pename,psal;

--允出準則
exit when cemp%notfound;

dbms_output.put_line(pename||‘的薪水是‘||psal);

end loop;

close cemp;
end;
/

 記錄型變數

----查詢並列印7839的姓名和薪水


set serveroutput on

declare
--記錄型變數 代表一行
emp_rec emp%rowtype;
begin

select * into emp_rec from emp where empno=7839;

dbms_output.put_line(emp_rec.ename||‘的薪水是‘||emp_rec.sal);
end;
/

執行個體1

/*
執行個體1:統計每年入職的員工個數。

SQL語句
1. select to_char(hiredate,‘RR‘) from emp; --> 游標 --> 迴圈(notfound)
2. count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
set serveroutput on

declare
cursor cemp is select to_char(hiredate,‘RR‘) from emp;
phiredate varchar2(4);

--計數器
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
begin
open cemp;
loop
--取一個員工
fetch cemp into phiredate;
exit when cemp%notfound;

--判斷年份
if phiredate = ‘80‘ then count80:=count80+1;
elsif phiredate = ‘81‘ then count81:=count81+1;
elsif phiredate = ‘82‘ then count82:=count82+1;
else count87:=count87+1;
end if;

end loop;
close cemp;

dbms_output.put_line(‘Total:‘||(count80+count81+count82+count87));
dbms_output.put_line(‘80:‘||count80);
dbms_output.put_line(‘81:‘||count81);
dbms_output.put_line(‘82:‘||count82);
dbms_output.put_line(‘87:‘||count87);
end;
/

 執行個體2

/*
為員工長工資。從最低工資調起每人長10%,但工資總額不能超過5萬元,
請計算長工資的人數和長工資後的工資總額,並輸出輸出長工資人數及工資總額。

SQL語句:
1. select empno,sal from emp order by sal;-->游標 -->迴圈(1. > 5w 2. 漲完)
2. countEmp number := 0;
3. 長工資後的工資總額: *. select sum(sal) from emp
*. 漲後=漲前+sal*0.1 (*)

練習: 工資<5w
*/
set serveroutput on
declare
cursor cemp is select empno,sal from emp order by sal;
pempno emp.empno%type;
psal emp.sal%type;

--人數
countEmp number := 0;

--工資總額
salTotal number;
begin
--初始的工資總額
select sum(sal) into salTotal from emp;

open cemp;
loop
--第一個允出準則
exit when salTotal> 50000;

--取一個員工
fetch cemp into pempno,psal;

--第二個允出準則
exit when cemp%notfound;

--漲工資
update emp set sal =sal *1.1 where empno=pempno;

--人數
countEmp := countEmp+1;


--工資總額
salTotal := salTotal + psal *0.1;
end loop;
close cemp;

commit;

dbms_output.put_line(‘人數:‘||countEmp||‘ 工資總額:‘||salTotal);

end;
/

 

執行個體3

 

/*
用PL/SQL語言編寫一程式,實現按部門分段(6000以上、(6000,3000)、3000元以下)
統計各工資段的職工人數、以及各部門的工資總額(工資總額中不包括獎金)

SQL語句
1. 部門: select deptno from dept; --> 游標 --> 迴圈
2. 部門中員工的薪水: select sal from emp where deptno=??? --> 帶參數的游標 --> 迴圈
3. count1 number; count2 number; count3 number;
4. 部門工資總額: salTotal number;
select sum(sal) into salTotal from emp where deptno=???
*/
set serveroutput on

declare
--部門
cursor cdept is select deptno from dept;
pdeptno dept.deptno%type;

--部門中員工的薪水
cursor cemp(dno number) is select sal from emp where deptno=dno;
psal emp.sal%type;

--計數器
count1 number; count2 number; count3 number;

--部門的工資總額
salTotal number;
begin
open cdept;
loop
--取一個部門
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);
loop
--取一個員工的薪水cl
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;

-- 儲存當前結果
insert into msg1 values(pdeptno,count1,count2,count3,nvl(salTotal,0));

end loop;
close cdept;

commit;

dbms_output.put_line(‘完成‘);
end;
/

系統例外

--被0除

set serveroutput on

declare
pnum number;
begin
pnum := 1/0;

exception
when Zero_Divide then dbms_output.put_line(‘1:0不能做被除數‘);
dbms_output.put_line(‘2:0不能做被除數‘);
when Value_error then dbms_output.put_line(‘算術或轉換錯誤‘);
when others then dbms_output.put_line(‘其他例外‘);
end;
/

--列印1~10

set serveroutput on

declare
pnum number := 1;
begin
loop
--退出迴圈
exit when pnum > 10;

dbms_output.put_line(pnum);

--加一
pnum := pnum + 1;

end loop;
end;
/

引用型變數

--查詢並列印7839的姓名和薪水

set serveroutput on

declare
--定義引用型變數
pename emp.ename%type;
psal emp.sal%type;
begin

--查詢7839的姓名和薪水
select ename,sal into pename,psal from emp where empno=7839;

-- 列印
dbms_output.put_line(pename||‘的薪水是‘||psal);
end;
/

自訂例外

--查詢50號部門的員工

set serveroutput on

declare
cursor cemp is select ename from emp where deptno=50;
pename emp.ename%type;

--自訂例外
no_emp_found exception;
begin
open cemp;

--取一個員工
fetch cemp into pename;

if cemp%notfound then
--拋出例外
raise no_emp_found;
end if;

--當拋出例外,自動關閉
close cemp;

exception
when no_emp_found then dbms_output.put_line(‘沒有找到員工‘);
when others then dbms_output.put_line(‘其他例外‘);
end;
/

out參數

/*
create [or replace] PROCEDURE 過程名(參數列表)
AS
PLSQL子程式體;
查詢並返回某個員工的姓名 月薪和職位

思考: out參數太多???
*/
create or replace procedure queryEmpInfo(eno in number,
pename out varchar2,
psal out number,
pjob out varchar2)
as
begin
select ename,sal,empjob into pename,psal,pjob from emp where empno=eno;

end;
/

觸發器應用情境二

/*
資料確認

漲後的薪水不能少於漲前的薪水
CREATE [or REPLACE] TRIGGER 觸發器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
[FOR EACH ROW [WHEN(條件) ] ]
PLSQL 塊

*/
create or replace trigger checksal
before update
on emp
for each row
begin
--if 漲後的薪水< 漲前的薪水 then
if :new.sal < :old.sal then
raise_application_error(-20002,‘漲後的薪水不能少於漲前的薪水.漲前:‘||:old.sal||‘ 漲後:‘||:new.sal);
end if;
end;
/

觸發器應用情境一

/*
實施複雜的安全性檢查

禁止在非工作時間 往emp表中插入資料
CREATE [or REPLACE] TRIGGER 觸發器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
PLSQL 塊

周末:to_char(sysdate,‘day‘) in (‘星期六‘,‘星期日‘)
上班前 下班後: to_number(to_char(sysdate,‘hh24‘)) not between 9 and 18
*/
create or replace trigger securityEmp
before insert
on emp
begin
if to_char(sysdate,‘day‘) in (‘星期六‘,‘星期日‘) or
to_number(to_char(sysdate,‘hh24‘)) not between 9 and 18 then

raise_application_error(-20001,‘不能在非工作時間插入資料‘);

end if;
end;
/

儲存函數

/*
CREATE [OR REPLACE] FUNCTION 函數名(參數列表)
RETURN 函數實值型別
AS
PLSQL子程式體;

查詢某個員工的年度營收

*/
create or replace function queryEmpIncome(eno in number)
return number
as
psal emp.sal%type;
pcomm emp.comm%type;
begin

select sal,comm into psal,pcomm from emp where empno=eno;

return psal*12+nvl(pcomm,0);
end;
/

帶參數的預存程序

/*
create [or replace] PROCEDURE 過程名(參數列表)
AS
PLSQL子程式體;

為指定的員工漲100塊錢 並列印漲前和漲後的薪水
*/
create or replace procedure raiseSalary(eno in number)
as
psal emp.sal%type;
begin
--漲前薪水
select sal into psal from emp where empno=eno;

--漲100
update emp set sal=sal+100 where empno=eno;

--要不要commit???

dbms_output.put_line(‘漲前:‘||psal||‘ 漲後:‘||(psal+100));

end;
/

第一個觸發器

/*
成功插入員工後,自動輸出“成功插入一個新員工”
CREATE [or REPLACE] TRIGGER 觸發器名
{BEFORE | AFTER}
{DELETE | INSERT | UPDATE [OF 列名]}
ON 表名
PLSQL 塊

*/
create or replace trigger sayNewEmp
after insert
on emp
begin
dbms_output.put_line(‘成功插入一個新員工‘);
end;
/

第一個預存程序

/*
create [or replace] PROCEDURE 過程名(參數列表)
AS
PLSQL子程式體;

列印Hello World

調用預存程序
1. exec sayHelloWorld();
2. begin
sayHelloWorld();
sayHelloWorld();
end;
/
*/

create or replace procedure sayHelloWorld
as
--說明部分
begin
dbms_output.put_line(‘Hello World‘);

end;
/

 

oracle第三天

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.