Linux 第68天 procedure,trigger,DCL

Linux 第68天 procedure,trigger,DCL

時間: 20181009

        個人博客地址: www.winthcloud.top


目錄

存儲過程簡介

觸發器

DCL (Data Countrol Language)


存儲過程簡介


SQL語句需要先編譯然後執行,而存儲過程(Stored Procedure)是一組爲了完成特定功能的

SQL語句集,經編譯後存儲在數據庫中,用戶通過指定存儲過程的名字並給定參數(如果該存儲

過程帶有參數)來調用執行它。


存儲過程是可編程的函數,在數據庫中創建並保存,可以由SQL語句和控制結構組成。當想要在

不同的應用程序或平臺上執行相同的函數,或者封裝特定功能時,存儲過程是非常有用的。數據

庫中的存儲過程可以看做是對編程中面向對象方法的模擬,它允許控制數據的訪問方式。


存儲過程的優點:

(1).增強SQL語言的功能和靈活性:存儲過程可以用控制語句編寫,有很強的靈活性,可以

完成複雜的判斷和較複雜的運算。


(2).標準組件式編程:存儲過程被創建後,可以在程序中被多次調用,而不必重新編寫該存

儲過程的SQL語句。而且數據庫專業人員可以隨時對存儲過程進行修改,對應用程序源代碼毫

無影響。


(3).較快的執行速度:如果某一操作包含大量的Transaction-SQL代碼或分別被多次執行,

那麼存儲過程要比批處理的執行速度快很多。因爲存儲過程是預編譯的。在首次運行一個存

儲過程時查詢,優化器對其進行分析優化,並且給出最終被存儲在系統表中的執行計劃。

而批處理的Transaction-SQL語句在每次運行時都要進行編譯和優化,速度相對要慢一些。


(4).減少網絡流量:針對同一個數據庫對象的操作(如查詢、修改),如果這一操作所涉及

的Transaction-SQL語句被組織進存儲過程,那麼當在客戶計算機上調用該存儲過程時,

網絡中傳送的只是該調用語句,從而大大減少網絡流量並降低了網絡負載。


(5).作爲一種安全機制來充分利用:通過對執行某一存儲過程的權限進行限制,能夠實現

對相應的數據的訪問權限的限制,避免了非授權用戶對數據的訪問,保證了數據的安全。


存儲過程與自定義函數的區別

存儲過程實現的過程要複雜一些,而函數的針對性較強

存儲過程可以有多個返回值,而自定義函數只有一個返回值

存儲過程一般獨立的來執行,而函數往往是作爲其他SQL語句的一部分來使用


流程控制

存儲過程和函數中可以使用流程控制來控制語句的執行

流程控制:

IF:用來進行條件判斷。根據是否滿足條件,執行不同語句

CASE:用來進行條件判斷,可實現比IF語句更復雜的條件判斷

LOOP:重複執行特定的語句,實現一個簡單的循環

LEAVE:用於跳出循環控制

ITERATE:跳出本次循環,然後直接進入下一次循環

REPEAT:有條件控制的循環語句。當滿足特定條件時,就會跳出循環語句

WHILE:有條件控制的循環語句


存儲過程: 存儲過程保存在mysql.proc表中


創建存儲過程

CREATE PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]])

routime_body

其中:proc_parameter: [IN|OUT|INOUT] parameter_name type

其中IN表示輸入參數,OUT表示輸出參數,INOUT表示既可以輸入也可以輸出;

param_name表示參數名稱;type表示參數的類型

查看存儲過程列表

SHOW PROCEDURE STATUS;


查看存儲過程定義

SHOW CREATE PROCEDURE sp_name;


調用存儲過程

CALL sp_name ([ proc_parameter [,proc_parameter ...]])

CALL sp_name

說明:當無參時,可以省略"()",當有參數時,不可省略"()"


存儲過程修改

ALTER語句修改存儲過程只能修改存儲過程的註釋等無關緊要的東西,不能修改存儲過程體

所以要修改存儲過程,方法就是刪除重建


刪除存儲過程

DROP PROCEDURE [IF EXISTS] sp_name;


存儲過程示

創建無參存儲過程

DELIMITER //

CREATE PROCEDURE showTime()

BEGIN

SELECT now();

END //

DELIMITER ;

CALL showTime;


創建含參存儲過程:只有一個IN參數

DELIMITER //

CREATE PROCEDURE selectById(IN uid SMALLINT UNSIGNED)

BEGIN

SELECT * FROM students WHERE stuid = uid;

END //

DELIMITER ;

CALL selectById(2);


只有一個IN參數(帶變量)

DELIMITER //

CREATE PROCEDURE dorepeat(n INT)

BEGIN

SET @i=0;

SET @sum=0;

REPEAT SET @sum = @sum+@i; SET @i=@i+1;

UNTIL @i > n END REPEAT;

END //

DELIMITER ;

CALL dorepeat(100);

SELECT @sum;


創建含參存儲過程:包含IN參數和OUT參數

DELIMITER //

CREATE PROCEDURE deleteById(IN uid SMALLINT UNSIGNED,

OUT num SMALLINT UNSIGNED)

BEGIN

DELETE FROM students WHERE stuid = uid;

SELECT row_count() INTO num;

END //

DELIMITER ;

CALL deleteById(2,@Line);

SELECT @Line;

說明:創建存儲過程deleteById,包含一個IN參數和一個OUT參數.調用時,傳入刪除的ID和

保存被修改的行數值的用戶變量@Line,select @Line;輸出被影響行數


觸發器

觸發器的執行不是由程序調用,也不是由手工啓動,而是由事件來觸發、激活從而實現執行

觸發器是與表有關的數據庫對象,在滿足定義條件時觸發,並執行觸發器中定義的語句集合。


觸發器的特性:

  有begin end體,begin end;之間的語句可以寫的簡單或者複雜

  觸發條件:I、D、U

  觸發機制:在增刪改前或者後

  觸發頻率:針對每一行執行

  觸發器定義附着在表上。


也就是由事件來觸發某個操作,事件包括INSERT語句,UPDATE語句和DELETE語句;可以協助

應用在數據庫端確保數據的完整性。

注意:cannot associate a trigger with a TEMPORARY table or a view.


創建觸發器

CREATE

[DEFINER = { user | CURRENT_USER }]

TRIGGER trigger_name

trigger_time trigger_event

ON tbl_name FOR EACH ROW

trigger_body

說明:

trigger_name:觸發器的名稱

trigger_time:{ BEFORE | AFTER },表示在事件之前或之後觸發

trigger_event::{ INSERT |UPDATE | DELETE },觸發的具體事件

tbl_name:該觸發器作用在表名

查看觸發器

SHOW TRIGGERS

查詢系統表information_schema.triggers的方式指定查詢條件,查看指定的觸發器信息。

mysql> USE information_schema;

mysql> SELECT * FROM triggers WHERE 

trigger_name='trigger_student_count_insert';

刪除觸發器

DROP TRIGGER trigger_name;


觸發器示例

CREATE TABLE student_info(

stu_id INT(11) NOT NULL AUTO_INCREMENT,

stu_name VARCHAR(255) DEFAULT NULL,

PRIMARY KEY(stu_id)

);


CREATE TABLE student_count(

student_count INT(11) DEFAULT 0

);


INSERT INTO student_count VALUES(0);

示例:創建觸發器,在向學生表INSERT數據時,學生數增加,DELETE學生時,學生數減少


CREATE TRIGGER trigger_student_count_insert

AFTER INSERT

ON student_info FOR EACH ROW

UPDATE student_count SET student_count=student_count+1;


CREATE TRIGGER trigger_student_delete

AFTER DELETE

ON student_info FOR EACH ROW

UPDATE student_count SET student_count=student_count-1;


DCL (Data Countrol Language)

GRANT REVOKE

用戶和權限管理


元數據數據庫:mysql

系統授權表:

db, host, user

columns_priv, tables_priv, procs_priv, proxies_priv


創建用戶:CREATE USER

CREATE USER 'USERNAME'@'HOST' [IDENTIFIED BY 'password'];

默認權限:USAGE

用戶重命名:RENAME USER

RENAME USER old_user_name TO new_user_name

刪除用戶:

DROP USER 'USERNAME'@'HOST‘

示例:刪除默認的空用戶

DROP USER ''@'localhost';


修改密碼:

mysql>SET PASSWORD FOR 'user'@'host' = PASSWORD('password');

mysql>UPDATE mysql.user SET password=PASSWORD('password') WHERE clause;

此方法需要執行下面指令才能生效:

mysql> FLUSH PRIVILEGES;

mysqladmin -u root -poldpass password 'newpass'

忘記管理員密碼的解決辦法:

啓動mysqld進程時,爲其使用如下選項:

--skip-grant-tables 表示跳過權限認證

--skip-networking 表示不啓用網絡接口

使用UPDATE命令修改管理員密碼

關閉mysqld進程,移除上述兩個選項,重啓mysqld


權限類別:

管理類:

CREATE TEMPORARY TABLES

CREATE USER

FILE

SUPER

SHOW DATABASES

RELOAD

SHUTDOWN

REPLICATION SLAVE

REPLICATION CLIENT

LOCK TABLES

PROCES

程序類: FUNCTION、PROCEDURE、TRIGGER

CREATE

ALTER

DROP

EXCUTE

庫和表級別:DATABASE、TABLE

ALTER

CREATE

CREATE VIEW

DROP

INDEX

SHOW VIEW

GRANT OPTION:能將自己獲得的權限轉贈給其他用戶

數據操作:

SELECT

INSERT

DELETE

UPDATE

字段級別:

SELECT(col1,col2,...)

UPDATE(col1,col2,...)

INSERT(col1,col2,...)

所有權限:ALL PRIVILEGES 或 ALL


授權

參考:https://dev.mysql.com/doc/refman/5.7/en/grant.html

GRANT priv_type [(column_list)],... 

ON [object_type] priv_level 

TO 'user'@'host' [IDENTIFIED BY 'password'] [WITH GRANT OPTION];

priv_type: ALL [PRIVILEGES]

object_type:TABLE | FUNCTION | PROCEDURE

priv_level: *(所有庫) | *.* | db_name.* | db_name.tbl_name | 

tbl_name(當前庫的表) | db_name.routine_name(指定庫的函數,存儲過程,觸發器)

with_option: GRANT OPTION

| MAX_QUERIES_PER_HOUR count

| MAX_UPDATES_PER_HOUR count

| MAX_CONNECTIONS_PER_HOUR count

| MAX_USER_CONNECTIONS count


回收授權

REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... 

ON [object_type] priv_level FROM user [, user] ...

示例:

REVOKE DELETE ON testdb.* FROM 'testuser'@'%‘

查看指定用戶獲得的授權:

Help SHOW GRANTS

SHOW GRANTS FOR 'user'@'host';

SHOW GRANTS FOR CURRENT_USER[()];

注意:MariaDB服務進程啓動時會讀取mysql庫中所有授權表至內存

(1) GRANT或REVOKE等執行權限操作會保存於系統表中,MariaDB的服務進程通常會自

動重讀授權表,使之生效

(2) 對於不能夠或不能及時重讀授權表的命令,可手動讓MariaDB的服務進程重讀授權表

mysql> FLUSH PRIVILEGES;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章