PL/SQL 編程

PL/SQL: (Procedural  Language)  過程化sql語言! html

    編程就是一種過程編程語言,至關於python中的函數java

    數據庫在執行PL/SQL語句的時候,PL和SQL是分別執行的!python

PL/SQL運算符sql

算術運算符

下表列出了全部PL/SQL支持的算術運算符。假設變量A=10和可變B=5,則:數據庫

BEGIN 
   dbms_output.put_line( 10 + 5);
   dbms_output.put_line( 10 - 5);
   dbms_output.put_line( 10 * 5);
   dbms_output.put_line( 10 / 5);
   dbms_output.put_line( 10 ** 5);
END;
算數運算符

當上述代碼在SQL提示符執行時,它產生了如下結果:編程

關係運算符

關係運算符比較兩個表達式或值,並返回一個布爾結果。下表列出了全部PL/SQL支持的關係運算符。假設變量A=10,變量B=20,則:oracle

DECLARE  --聲明
   a number (2) := 21;
   b number (2) := 10;
BEGIN    --開始
   IF (a = b) then
      dbms_output.put_line('Line 1 - a is equal to b');
   ELSE
      dbms_output.put_line('Line 1 - a is not equal to b');
   END IF;  --結束循環

   IF (a < b) then
      dbms_output.put_line('Line 2 - a is less than b');
   ELSE
      dbms_output.put_line('Line 2 - a is not less than b');
   END IF;  --結束循環
   
   IF ( a > b ) THEN
      dbms_output.put_line('Line 3 - a is greater than b');
   ELSE
      dbms_output.put_line('Line 3 - a is not greater than b');
   END IF;  --結束循環

   -- Lets change value of a and b
   a := 5;
   b := 20;
   IF ( a <= b ) THEN
      dbms_output.put_line('Line 4 - a is either equal or less than b');
   END IF;

   IF ( b >= a ) THEN
      dbms_output.put_line('Line 5 - b is either equal or greater than a');
   END IF;
   
   IF ( a <> b ) THEN
      dbms_output.put_line('Line 6 - a is not equal to b');
   ELSE
      dbms_output.put_line('Line 6 - a is equal to b');
   END IF;

END; --結束
關係運算符

當上述代碼在SQL提示符執行時,它產生了如下結果:less

比較運算符

比較運算符用於一個表達比較到另外一個。結果老是 TRUE,FALSE或NULL。數據庫設計

--LIKE 運算符
--這個程序測試LIKE運算符,將學習如何在PL/ SQL程序使用,但這裏用一個程序來顯示LIKE運算符的功能:
DECLARE
PROCEDURE compare (value  varchar2,  pattern varchar2 ) is
BEGIN
   IF value LIKE pattern THEN
      dbms_output.put_line ('True');
   ELSE
      dbms_output.put_line ('False');
   END IF;
END;

BEGIN
   compare('Zara Ali', 'Z%A_i');
   compare('Nuha Ali', 'Z%A_i');
END;
Like運算符

當上述代碼在SQL提示符執行時,它產生了如下結果:編程語言

--BETWEEN運算符
--下面的程序顯示了運算符BETWEEN的用法
DECLARE
   x number(2) := 10;
BEGIN
   IF (x between 5 and 20) THEN
      dbms_output.put_line('True');
   ELSE
      dbms_output.put_line('False');
   END IF;
   
   IF (x BETWEEN 5 AND 10) THEN
      dbms_output.put_line('True');
   ELSE
      dbms_output.put_line('False');
   END IF;
   
   IF (x BETWEEN 11 AND 20) THEN
      dbms_output.put_line('True');
   ELSE
      dbms_output.put_line('False');
   END IF;
END;
BETWEEN運算符

當上述代碼在SQL提示符執行時,它產生了如下結果:

--IN和IS NULL運算符
--下面的程序顯示IN和IS NULL運算符的用法
DECLARE
   letter varchar2(1) := 'm';
BEGIN
   IF (letter in ('a', 'b', 'c')) THEN
      dbms_output.put_line('True');
   ELSE
      dbms_output.put_line('False');
   END IF;
 
   IF (letter in ('m', 'n', 'o')) THEN
       dbms_output.put_line('True');
   ELSE
      dbms_output.put_line('False');
   END IF;
   
   IF (letter is null) THEN
    dbms_output.put_line('True');
   ELSE
      dbms_output.put_line('False');
   END IF;
END;
IN和IS NULL運算符

當上述代碼在SQL提示符執行時,它產生了如下結果:

 

邏輯運算符

下表顯示了PL/SQL支持的邏輯運算符。全部這些操做符布爾運算,併產生布爾結果。假設變量A=true,變量B=false

DECLARE
   a boolean := true;
   b boolean := false;
BEGIN
   IF (a AND b) THEN
      dbms_output.put_line('Line 1 - Condition is true');
   END IF;
   IF (a OR b) THEN
      dbms_output.put_line('Line 2 - Condition is true');
   END IF;
   IF (NOT a) THEN
      dbms_output.put_line('Line 3 - a is not true');
   ELSE
      dbms_output.put_line('Line 3 - a is true');
   END IF;
   IF (NOT b) THEN
      dbms_output.put_line('Line 4 - b is not true');
   ELSE
      dbms_output.put_line('Line 4 - b is true');
   END IF;
END;
邏輯運算符

 當上述代碼在SQL提示符執行時,它產生了如下結果:

PL/SQL運算符優先級

運算符優先級肯定表達式分組。這會影響一個表達式是如何進行計算。某些運算符的優先級高於其餘運算符; 例如,乘法運算符的優先級比加法運算高:

例如 x =7 + 3* 2; 這裏,x被賦值13,而不是20,由於運算符*具備優先級高於+,因此它首先被乘以3 * 2,而後再加上7。

這裏,具備最高優先級的操做出如今表的頂部,那些具備最低出如今底部。在表達式,更高的優先級運算符將首先計算。

DECLARE
   a number(2) := 20;
   b number(2) := 10;
   c number(2) := 15;
   d number(2) := 5;
   e number(2) ;
BEGIN
   e := (a + b) * c / d;      -- ( 30 * 15 ) / 5
   dbms_output.put_line('Value of (a + b) * c / d is : '|| e );

   e := ((a + b) * c) / d;   -- (30 * 15 ) / 5
   dbms_output.put_line('Value of ((a + b) * c) / d is  : ' ||  e );

   e := (a + b) * (c / d);   -- (30) * (15/5)
   dbms_output.put_line('Value of (a + b) * (c / d) is  : '||  e );

   e := a + (b * c) / d;     --  20 + (150/5)
   dbms_output.put_line('Value of a + (b * c) / d is  : ' ||  e );
END;
運算符

當上述代碼在SQL提示符執行時,它產生了如下結果:

|| 拼接字符串
:= 賦值運算符
= 比較運算符 相似與java中的==
.. 範圍運算符  1-10
!= <> ~= ^=  4種不等於
and 邏輯與
or 邏輯或
not 取反

 

PL/SQL語法:

1.declare 可選部分 ==》聲明

2.begin 必須有 ==》書寫sql 和 pl/sql

3.exception 可選部分 ==》異常

4.end 必須有 ==》pl/sql代碼塊結束

 事例1:loop循環語法

--loop循環語法:
declare    --聲明部分
  i number;
begin      --開始
  i:=1;
  loop     --循環開始
    dbms_output.put_line(i);   --輸出語句
    i:=i+1;
    exit when i=10;
  end loop; --循環結束
  
end;  --結束
loop循環語法

事例2:while循環語法

declare    --聲明部分
  i number;
begin      --代碼開始
  
  i:=1;
 while i<8 loop     --循環開始
    dbms_output.put_line(i);   --輸出語句
    i:=i+1;
  end loop; --循環結束
end;        --結束部分
while循環語法

事例3:for循環語法

declare    --聲明部分
  i number;
  
begin      --代碼開始
  
 for  i in 1..9 loop     --循環開始
    dbms_output.put_line(i);   --輸出語句
  end loop; --循環結束
  
end;        --結束部分
for循環語法

事例4:根據老師的薪水輸出不一樣的語句!

declare
  t_name  teacher.tname%type;  --說t_name的類型根據teacher表中tname的類型來決定
  t_sal   teacher.sal%type;
  t_result  varchar2(50);
begin    --開始
  select  tname,sal into t_name,t_sal   from teacher where tno=1002; --查詢指定老師的薪水
  
    if t_sal>5000 and t_sal<10000 then   -- 多重if
      t_result:='一級';
    elsif t_sal>=10000 and t_sal<20000 then
      t_result:='二級';
    else
      t_result:='高級';
    end if;  
    --根據t_result的值來判斷輸入語句    switch
    case t_result
        when '一級' then
        dbms_output.put_line('哈哈....');
        when '二級' then
        dbms_output.put_line('通常般....');
        when '高級' then
        dbms_output.put_line('能夠啊....');      
    end case;
end;     --結束
根據老師的薪水輸出不一樣語句

上述稍有問題

事例5:函數,將身份證中的出生日期隱藏起來

create or replace  function fn_teacher_tid(f_tid varchar2)
return varchar2     --建立一個函數  傳遞一個varchar2類型的值 返回一個varchar2類型的值
is
 f_result varchar2(50);    --聲明變量
begin      --開始書寫函數內容
  if length(f_tid)!=18 then
    dbms_output.put_line('身份證格式不正確');
    else
    dbms_output.put_line('身份證格式正確'); 
  end if;
    f_result:= substr(f_tid,1,6)||'********'||substr(f_tid,15);
    return f_result;
end fn_teacher_tid;   --函數結束

--調用函數  須要現將函數執行 放入到Functions中  沒有出錯時再調用方法
select fn_teacher_tid('41302619921215935X') from dual;
函數,將身份證中的出生日期隱藏起來

執行結果出生日期8位數字被隱藏

事例6:隱式遊標

begin    --  隱式遊標    自動建立
     update teacher set tname='我是隱式遊標' where tno=1002;  --修改
    if sql%found  then
       dbms_output.put_line('教師的信息已經更改'||sql%rowcount);
       else
       dbms_output.put_line('更改失敗');
    end if;      
end;
隱式遊標

 

 事例7:顯示遊標

declare    --聲明 顯示遊標
  c_tname  teacher.tname%type;
  c_sal    teacher.sal%type;
cursor  teacher_cursor
is
select tname,sal from teacher where tno<1005;  --遊標數據來源
begin
  open teacher_cursor;  --打開遊標
   fetch teacher_cursor into c_tname,c_sal;--使用遊標
    while teacher_cursor%found  loop      
      dbms_output.put_line('教師的姓名是==》'||c_tname);
      dbms_output.put_line('教師的薪水是==》'||c_sal); 
      fetch teacher_cursor into c_tname,c_sal;--逐行讀取  
    end loop;
  close teacher_cursor;   --關閉遊標
end;
顯示遊標

 

判斷條件tno<1005  顯示老師的姓名和工資

 

遊標 :
01.是oracle系統給咱們用戶開設的一個數據緩衝區!
02.存放的是sql語句執行的結果集!
03.每一個遊標區都有一個名稱,用戶經過遊標逐行獲取須要的數據!

分類:
01.隱式遊標: 非查詢語句
  只要咱們使用pl/sql,程序在執行sql語句的時候 自動建立! 遊標區===》sql
02.顯示遊標: 返回多行記錄
03.REF遊標(動態遊標): 處理運行時才能肯定的動態sql查詢結果

遊標的經常使用屬性:
01.sql%found 影響了一行或者多行數據 返回true
02.sql%notfound 沒有影響行 返回true
03.sql%rowcount 返回true影響行數
04.sql%isopen 遊標是否打開!始終是false

使用遊標的步驟:
01.聲明遊標
02.打開遊標
03.使用遊標獲取記錄
04.關閉遊標

事例8:觸發器

觸發器只針對於增刪改! 

update :old :new
insert :new
delete :old

:old 表明修改以前的值
:new 表明修改以後的值

-- 建立一個用於保存teacher操做記錄的表
create  table  teacher_log
(
logid  number  not null,
old_value varchar2(150),
create_date date,
log_type  number,
t_no number
);
--建立主鍵
alter  table  teacher_log add  constraint pk_teacher_logid 
primary key(logid);

-- 建立序列
create  sequence sq_teacherLog_logid
minvalue 1
maxvalue 99999999999
start with 1
increment by 1;

--  建立觸發器
create or replace trigger  tr_teacher
after insert or update or delete    --會在增刪改以後 觸發
on teacher for each row   --做用在teacher表中的每一行
declare   --聲明變量
old_value    teacher_log.old_value%type;
log_type     teacher_log.log_type%type;
t_no         teacher_log.t_no%type;
begin
    if inserting  then
      log_type:=1; --新增
      t_no:=:new.tno;
      old_value:=:new.tname||'*****'||:new.sal;
    elsif deleting  then
       log_type:=2; --刪除
      t_no:=:old.tno;
      old_value:=:old.tname||'*****'||:old.sal;
     else
       log_type:=3; --修改
       t_no:=:old.tno;
      old_value:=:old.tname||'*****'||:old.sal||'如今的薪水:'||:new.sal;
    end  if;  
  
--把用戶修改的數據 放入 teacher_log
insert into  teacher_log
values(sq_teacherLog_logid.nextval,old_value,sysdate,log_type,t_no);    
end tr_teacher;  --結束
select * from teacher
select * from teacher for update
select * from teacher_log
觸發器

 先執行添加語句  打開表中的鎖、修改金額、點擊對號,提交事務

select * from teacher for update

執行查詢teacher_log表,能夠看到被修改的數據

select * from teacher_log

刪除表中第二條數據 TNO=1009  秦亞傑 打開表中的鎖、刪除字段、點擊對號,提交事務

 

執行查詢teacher_log表,能夠看到被刪掉的數據

select * from teacher_log

偷偷增長一條數據,本身人將工資多給點,打開表中的鎖、添加行、新增數據、點擊對號,提交事務

執行查詢teacher_log表,能夠看到增長信息

 在Oracle中增刪改都須要手動去提交事務

事例9:存儲過程

 

爲了完成一個特定的功能而實現編寫一組sql語句的集合!

新增數據時,若是身份證號碼不足18位,報錯!

create or replace  procedure  pro_addTeacher   --存儲過程
(
p_no      teacher.tno%type,
p_name     teacher.tname%type,
p_tid      teacher.tid%type
)
is
ex_tidException  exception;  --異常類型

begin
   if length(p_tid)!=18 then
     raise ex_tidException;   --拋出異常
    end if; 
    
    --新增
    insert  into  teacher(tno,tname,tid)
    values(p_no,p_name,p_tid);
    commit;  --- 自動提交
    
exception    -- 異常處理部分
   when ex_tidException then
     dbms_output.put_line('身份證號不正確');
    when others then
     dbms_output.put_line('其餘異常');
  
end pro_addTeacher;   --結束

--調用存儲過程
call pro_addTeacher(1000,'新增','112222222222222222');
select * from teacher
select * from teacher for update
存儲過程

 

 

身份證號等於18位時,數據添加成功

 

name teacher.tname%type :會根據表中字段的類型,自動改變!

teacherRow teacher%rowtype: 一整行的記錄,包括不少字段!

teacherRow.name

 

數據庫的設計(DataBase Design):針對於用戶特定的需求,而後咱們建立出來一個最使用並且性能高的數據庫!

數據庫設計的步驟:

01.需求分析 
02.概念結構設計
03.邏輯結構設計
04.物理結構設計
05.數據庫的實施
06.數據庫的運行和維護

數據庫的3大範式:

1.確保每列的原子性!每一列都是一個不可再分的數據!
2.確保每列都和主鍵相關!
3.確保每列都和主鍵有直接的管理,而不是間接依賴(傳遞依賴)!

 

 
 
 

源於:https://www.cnblogs.com/wqtzhaoqiang/p/7853486.html

相關文章
相關標籤/搜索