存儲過程和觸發器——MySQL

jopen 9年前發布 | 15K 次閱讀 MySQL 數據庫服務器

MySQL5.0版本開始就對存儲過程和觸發器進行了支持,在MySQL進行學習前,先查看您所使用的版本吧,方法有:

1.$mysql -V  //linux終端下

2.select version();  //mysql

3. mysql --help | grep Distrib  //linux終端下

在了解您所使用的版本支持情況下再下一步

存儲過程  sql語句執行的時候要先編譯,然后執行。存儲過程(Stored Procedure)是一組為了完成特定功能的SQL語句集,經編譯后存儲在數據庫中。用戶通過指定存儲過程的名字并給出參數(如果該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象,任何一個設計良好的數據庫應用程序都應該用到存儲過程。
  
一、存儲過程介紹
  
存儲過程是由流控制和SQL語句書寫的過程,這個過程經編譯和優化后存儲在數據庫服務器中,應用程序使用時只要調用即可。在ORACLE中,若干個有聯系的過程可以組合在一起構成程序包。
  
存儲過程是利用SQL Server所提供的Tranact-SQL語言所編寫的程序。Tranact-SQL語言是SQL Server提供專為設計數據庫應用程序的語言,它是應用程序和SQL Server數據庫間的主要程序式設計界面。它好比Oracle數據庫系統中的Pro-SQLInformix的數據庫系統能夠中的Informix- 4GL語言一樣。這類語言主要提供以下功能,讓用戶可以設計出符合引用需求的程序:
  1)
、變量說明
  2)
ANSI兼容的SQL命令(Select,Update….)
  3)
、一般流程控制命令(if…else…while….)
  4)
、內部函數
  
二、使用存儲過程有以下的優點:
  * 
存儲過程的能力大大增強了SQL語言的功能和靈活性。存儲過程可以用流控制語句編寫,有很強的靈活性,可以完成復雜的判斷和較復雜的運算。
  * 
可保證數據的安全性和完整性。
  # 
通過存儲過程可以使沒有權限的用戶在控制之下間接地存取數據庫,從而保證數據的安全。
  # 
通過存儲過程可以使相關的動作在一起發生,從而可以維護數據庫的完整性。
  * 
再運行存儲過程前,數據庫已對其進行了語法和句法分析,并給出了優化執行方案。這種已經編譯好的過程可極大地改善SQL語句的性能。由于執行SQL語句的大部分工作已經完成,所以存儲過程能以極快的速度執行。
  * 
可以降低網絡的通信量。
  * 
使體現企業規則的運算程序放入數據庫服務器中,以便:
  # 
集中控制。
  # 
當企業規則發生變化時在服務器中改變存儲過程即可,無須修改任何應用程序。企業規則的特點是要經常變化,如果把體現企業規則的運算程序放入應用程序中,則當企業規則發生變化時,就需要修改應用程序工作量非常之大(修改、發行和安裝應用程序)。如果把體現企業規則的運算放入存儲過程中,則當企業規則發生變化時,只要修改存儲過程就可以了,應用程序無須任何變化。
   
三、存儲過程的書寫格式:
  CREATE PROCEDURE [
擁有者.]存儲過程名[;程序編號]
  [(
參數#1,…參數#1024)]
  [WITH
  {RECOMPILE | ENCRYPTION | RECOMPILE, ENCRYPTION}
  ]
  [FOR REPLICATION]
  AS 
程序行

其中存儲過程名不能超過128個字。每個存儲過程中最多設定1024個參數
  (SQL Server 7.0
以上版本),參數的使用方法如下:
  @
參數名數據類型 [VARYING] [=內定值] [OUTPUT]
  
每個參數名前要有一個“@”符號,每一個存儲過程的參數僅為該程序內部使用,參數的類型除了IMAGE外,其他SQL Server所支持的數據類型都可使用。

  output:表示此參數是可傳回的
  with {recompile|encryption}
  recompile:
表示每次執行此存儲過程時都重新編譯一次
  encryption:
所創建的存儲過程的內容會被加密

實例:

建立2張表格employeedepartment,他們以員工ID建立關系

1. 創建2表:

create table employee (
     employee_id int(5) primary key not null,
     employee_name varchar(20),
     employee_salary int(5));

create table department (
     dept_id int(3),
     dept_name varchar(20),
     employee_id int(5),
     constraint fk_employee_id foreign key(employee_id) references employee(employee_id));

2. employee創建添加記錄的存儲過程

 在這之前,需要設置一下分隔符,以免后面使用;時就終止了創建

delimiter //
create procedure add_employee(in id int,in name varchar(20),in salary int)  /*
參數輸入的形式,in:輸入,若為輸出,則為out*/
  begin
  insert into employee values(id,name,salary);  #
輸入的數據插入到表格中
  select * from employee;
  end//  #
這里就以//結束程序的錄入

3.department創建添加記錄的存儲過程

create procedure insert_dept(in id int,in name varchar(20),in emp_id int)
  begin
  insert into department values(id,name,emp_id);
  select * from department;
  end;//

4. 調用存儲過程完成數據錄入

call add_employee(2,'Jason',6500);//
call insert_dept(1,'STE',2);//

5.創建一個給指定部門員工加薪的存儲過程

create procedure raise (in department_id int,in add_salary_amount int)
  begin
  update employee set employee_salary=employee_salary+add_salary_amount
     where employee_id in ( select employee_id from department where department_id=dept_id);
  commit;
  end;//

call raise(1,200);//

觸發器  觸發器(trigger)是個特殊的存儲過程,它的執行不是由程序調用,也不是手工啟動,而是由個事件來觸發,比如當對一個表進行操作( insertdelete update)時就會激活它執行。觸發器經常用于加強數據的完整性約束和業務規則等。觸發器可以從DBA_TRIGGERSUSER_TRIGGERS數據字典中查到。

觸發器介紹
觸發器是一種特殊的存儲過程,它在插入,刪除或修改特定表中的數據時觸發執行,它比數據庫本身標準的功能有更精細和更復雜的數據控制能力。數據庫觸發器有以下的作用:
安全性。可以基于數據庫的值使用戶具有操作數據庫的某種權利。
可以基于時間限制用戶的操作,例如不允許下班后和節假日修改數據庫數據。
可以基于數據庫中的數據限制用戶的操作,例如不允許股票的價格的升幅一次超過10%
審計。可以跟蹤用戶對數據庫的操作。
審計用戶操作數據庫的語句。
把用戶對數據庫的更新寫入審計表。
實現復雜的數據完整性規則。 #實現非標準的數據完整性檢查和約束。觸發器可產生比規則更為復雜的限制。與規則不同,觸發器可以引用列或數據庫對象。例如,觸發器可回退任何企圖吃進超過自己保證金的期貨。
提供可變的缺省值。
實現復雜的非標準的數據庫相關完整性規則。觸發器可以對數據庫中相關的表進行連環更新。#在修改或刪除時級聯修改或刪除其它表中的與之匹配的行。
在修改或刪除時把其它表中的與之匹配的行設成NULL值。
在修改或刪除時把其它表中的與之匹配的行級聯設成缺省值。

觸發器能夠拒絕或回退那些破壞相關完整性的變化,取消試圖進行數據更新的事務。當插入一個與其主健不匹配的外部鍵時,這種觸發器會起作用。

同步實時地復制表中的數據。
自動計算數據值,如果數據的值達到了一定的要求,則進行特定的處理。例如,如果公司的帳號上的資金低于5萬元則立即給財務人員發送警告數據。

觸發器語法
create  trigger 
觸發器名觸發時間觸發事件
on 
表名
[for each row]
pl/sql 
語句
其中:
觸發器名:觸發器對象的名稱。由于觸發器是數據庫自動執行的,因此該名稱只是一個名稱,沒有實質的用途。
觸發時間:指明觸發器何時執行,該值可取:
before---
表示在數據庫動作之前觸發器執行;
after---
表示在數據庫動作之后出發器執行。
觸發事件:指明哪些數據庫動作會觸發此觸發器:
insert
:數據庫插入會觸發此觸發器;
update
:數據庫修改會觸發此觸發器;
delete
:數據庫刪除會觸發此觸發器;

名:數據庫觸發器所在的表。

.使用觸發機制時的限制
當你在使用觸發機制時你必須要知道它有如下的使用限制:
不能在臨時表中創建觸發機制
觸發機制必須在當前的表所在的數據庫中創建
不能在視圖中創建觸發機制
當表被刪除以后所有與之相關的觸發機制會被自動地刪除

實例:

6. 記錄員工薪資變更日志

這時就可以對salary創建一個觸發器,記錄變更信息,先創建一個記錄日志的表格:

create table salary_adjust_log(
  employee_id int(5),
  old_salary int(4),
  new_salary int(4),
  changedata datetime);//   #
使用datetime格式記錄變更時間

創建觸發器:

create trigger update_salary
  after update on employee
  for each row       #
對表格每一行執行
  begin
  insert into salary_adjust_log
    values(new.employee_id,  /*new:
表示更新后的記錄,old:更新前的記錄,在oracle中語法是 :new.employee_id,:old employee_salary,多了個冒號*/
      old.employee_salary,  
      new.employee_salary,
      now());   #
使用now()函數記錄時間
  end;//


 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!