Oracle PL/SQL學習筆記

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
 

 

發佈了25 篇原創文章 · 獲贊 0 · 訪問量 3684
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章