Oracle PL/SQL 學習筆記
-- 案例 create or replace procedure sp_pro2 is begin -- 執行部分 delete from mytest where name ='name1'; end; -- 最簡單的塊 begin qdbms_output.put_line('hello world'); end; --- 有定義和執行部分的塊 declare --定義變量 v_ename varchar2(5); v_sal number(7,2); begin -- 執行部分 select ename,sal into v_ename,v_sal from emp where empno = &no; /* select sal into v_sal from emp where empno = &no;*/ dbms_output.put_line('employeer: ' || v_ename || ' salary: ' || v_sal); exception -- 異常處理 when no_data_found then dbms_output.put_line('朋友,請重新輸入編號'); end; / -- 案例4 create procedure sp_pro3(spName varchar2,newSal number) is begin --執行部分-- 根據用戶名去修改工資 update emp set sal = newSal where ename =spName; end; -- 函數案例 -- 輸入僱員的姓名,返回該僱員的年薪 create function sp_fun2(spName varchar2) return number is yearSal number(7,2); begin --執行部分 select sal * 12 + nvl(comm,0) * 12 into yearSal from emp where ename = spName; return yearSal; end; -- 創建包 -- 創建一個包 sp_package -- 聲明該包有一個過程 -- 聲明該包有一個函數 create package sp_package is procedure update_sal(name varchar2,newsal number); function annual_income(name varchar2) return number; end; -- 給包 sp_package 實現包體 create or replace package body sp_package is procedure update_sal(name varchar2,newsal number) is begin update emp set sal = newsal where ename = name; end; function annual_income(name varchar2) return number is annual_salary number; begin select sal*12+nvl(comm,0) into annual_salary from emp where ename = name; return annual_salary; end; end; -- 案例 declare c_tax_rate number(3,2):=0.03; --用戶名 v_ename emp.ename%type; v_sal number(7,2); v_tax_sal number(7,2); begin --執行部分 select ename,sal into v_ename,v_sal from emp where empno=&no; --計算所得稅 v_tax_sal:=v_sal*c_tax_rate; --輸出 dbms_output.put_line('姓名:' || v_ename ||',工資:' || v_sal || '所得稅:'|| v_tax_sal); end; --pl/sql記錄實例 declare --定義一個pl/sql記錄類型emp_record_type, -- 類型保護三個數據name,salary,title type emp_record_type is record( name emp.ename%type, salary emp.sal%type, title emp.job%type ); -- 定義了一個sp_record變量,這個變量類型是emp_record_type sp_record emp_record_type; begin select ename,sal,job into sp_record from emp where empno=7788; dbms_output.put_line('員工名:' || sp_record.name || ',工資是' || sp_record.salary); end; -- pl/sql 表實例 declare -- 定義一個pl/sql表類型sp_table_type,該類型是用於存放emp.ename%type -- index by binary_integer表示下標是整數 type sp_table_type is table of emp.ename%type index by binary_integer; -- 定義一個sp_table變量,這個變量的類型是sp_table_type sp_table sp_table_type; begin select ename into sp_table(0) from emp where empno=7788; dbms_output.put_line('員工名:' || sp_table(0)); end; -- pl/sql cursor實例 declare -- 定義遊標類型 type sp_emp_cursor is ref cursor; -- 定義一個遊標變量 test_cursor sp_emp_cursor; -- 定義變量 v_ename emp.ename%type; v_sal emp.sal%type; begin -- 執行部分 -- 把test_cursor 和一個select結合 open test_cursor for select ename,sal from emp where deptno=&no; --循環取出 loop fetch test_cursor into v_ename,v_sal; -- 判斷工資高低,決定是否更新 -- 判斷是否test_cursor爲空 exit when test_cursor%notfound; dbms_output.put_line('名字:'||v_ename||',工資:'|| v_sal); end loop; end; -- procedure test create or replace procedure sp_pro6(spName varchar2) is --定義 v_sal emp.sal%type; begin --執行 select sal into v_sal from emp where ename=spName; --判斷 if v_sal <2000 then update emp set sal = sal*1.1 where ename=spName; end if; end; -- procedure test2 create or replace procedure sp_pro6(spName varchar2) is --定義 v_comm emp.comm%type; begin --執行 select comm into v_comm from emp where ename=spName; --判斷 if v_comm != 0 then update emp set comm =comm + 100 where ename=spName; else update emp set comm = comm + 200 where ename=spName; end if; end; -- procedure if elsif create or replace procedure sp_pro6(spNo number) is -- 定義 v_job emp.job%type; begin -- 執行 select job into v_job from emp where empno = spNo; if v_job = 'PRESIDENT' then update emp set sal = sal + 1000 where empno = spNo; elsif v_job = 'MANAGER' then update emp set sal = sal + 500 where empno = spNo; else update emp set sal = sal + 200 where empno = spNo; end if; end; -- loop test create or replace procedure sp_pro6(spName varchar2) is -- 定義 :=表示賦值 v_num number:=1; begin loop insert into users values(v_num,spName); -- 判斷退出條件 exit when v_num = 10; -- 自增 v_num:= v_num +1; end loop; end; -- while test; create or replace procedure sp_pro6(spName varchar2) is -- 定義 :=表示賦值 v_num number:=11; begin while v_num <=20 loop -- 執行 insert into users values(v_num,spName); v_num:=v_num+1; end loop; end; -- goto test declare i int := 1; begin loop dbms_output.put_line('i=' || i); if i = 10 then goto end_loop; end if; i := i + 1; end loop; <<end_loop>> dbms_output.put_line('end loop'); end; -- 創建表 create table book( bookId number(4,2), bookName varchar2(50), publishHouse varchar2(50) ); -- 編寫過程 -- in 表示輸入參數, 默認爲in -- out 表示輸出參數 create or replace procedure sp_pro7(spBookId in number, spbookName in varchar2, sppublishHouse in varchar) is begin insert into book values(spBookId,spbookName,sppublishHouse); end; -- 有輸入和輸出的存儲過程 create or replace procedure sp_pro8 (spNo in number,spName out varchar2, spSal out number,spJob out varchar2) is begin select ename,sal,job into spName,spSal,spJob from emp where empno = spNo; end; -- 返回結果集的過程 -- 1.創建一個包,在該包中定義一個類型test_cursor,一個遊標 create or replace package testpackage as type test_cursor is ref cursor; end testpackage; -- 2. 創建存儲過程 create or replace procedure sp_pro9(spNo in number, p_cursor out testpackage.test_cursor) is begin open p_cursor for select * from emp where deptno=spNo; end; -- 3. 如何在java中調用 -- oracle 的分頁 select rownum rn,t1.* from (select * from emp) t1 select rownum rn,t1.* from (select * from emp) t1 where rownum < 10; -- 在分頁時,大家可以把下面的sql語句當成模板使用 select * from (select rownum rn,t1.* from (select * from emp) t1 where rownum <= 10) where rn >= 6; -- 開發一個包 create or replace package testPackage as type test_cursor is ref cursor; end testPackage; -- 開始編寫分頁的過程 create or replace procedure fenye (tableName in varchar2, pageSize in number, -- 一頁現實記錄數 pageNow in number, myrows out number, -- 總記錄數 myPageCount out number, -- 總頁數 p_cursor out Testpackage.test_cursor -- 返回記錄集 ) is -- 定義部分 -- 定義sql語句 字符串 v_sql varchar2(1024); -- 定義兩個整數 v_begin number:=(pageNow-1)*pageSize + 1; v_end number:=pageNow*pageSize; begin -- 執行部分 v_sql:='select * from (select rownum rn,t1.* from (select * from '|| tableName||' order by sal) t1 where rownum <= '||v_end||') where rn >= '||v_begin||''; -- 把遊標和sql語句關聯起來 open p_cursor for v_sql; -- 計算myRows和myPageCount -- 組織一個SQL v_sql:='select count(*) from ' || tableName; -- 執行SQL,並把返回的值,賦給myRows execute immediate v_sql into myRows; -- 計算myPageCount if mod(myRows,pageSize)=0 then myPageCount := myRows/pageSize; else myPageCount := myRows/pageSize + 1; end if; -- 關閉遊標 -- close p_cursor; end; -- 使用java測試 -- 新的需要,排序 -- 例外案例 declare -- 定義 v_name emp.ename%type; begin select ename into v_name from emp where empno = &no; dbms_output.put_line('name: '|| v_name); exception when no_data_found then dbms_output.put_line('no not exist'); end; -- 自定義例外 create or replace procedure ex_test(spNo number) is -- 定義一個例外 myex exception; begin -- 更新用戶sal update emp set sal = sal + 1000 where empno= spNo; -- sql%notfound 這是表示沒有update -- raise myex; 觸發myex if sql%notfound then raise myex; end if; exception when myex then dbms_output.put_line('not update success'); end; -- 創建視圖,把emp表薪水sal<1000 的僱員映射該視圖(view) create view myview as select * from emp where sal < 1000; create view myview as select emp.empno,emp.ename,dept.dname from emp,dept where emp.deptno = dept.deptno