MySql基礎教程二(視圖,存儲過程,遊標,觸發器,事務,權限,數據類型)

我的學習資料是《MySQL必知必會》,被稱爲sql入門經典,PDF版下載點我。
相關鏈接:
MySql基礎教程一(查詢,插入,更新,刪除,創建)

視圖

視圖是虛擬的表。與包含數據的表不一樣,視圖只包含使用時動態檢索數據的查詢。比如下面的語句:

select cust_name, cust_contact from customers, orders, orderitems 
where customers.cust_id=orders.cust_id and 
orders.order_num=orderitems.order_num and
orderitems.prod_id='TNT2';

如果使用視圖,可以將整個查詢包裝成一個名爲productcustomers的虛擬表,則採用下面的查詢即可得到相同的結果:

select cust_name, cust_contact from productcustomers where prod_id='TNT2';

這就是視圖的作用,productcustomers是一個視圖,作爲視圖,它不包含表中應該有的任何數據,它包含的是一個sql查詢。創建上述視圖的方法:

create view productcustomers as
select cust_name, cust_contact, prod_id from customers, orders, orderitems
where customers.cust_id=orders.cust_id and orderitems.order_num=orders.order_num;

在視圖創建之後,可以用與表基本相同的方式利用它們。可以對視圖進行select操作,過濾和排序操作,將視圖聯接到其他視圖或表,甚至能添加和更新數據,但是更新一個視圖將更新其基表,儘量將視圖用於檢索,而不是更新
使用show create view viewname; 來查看視圖;用drop刪除視圖,其語法爲drop view viewname;。更新視圖時,可以先用drop,再用create,也可以使用create or replace view

視圖的好處:
1,重用sql語句;
2,簡化複雜的sql操作。在編寫查詢後,可以方便的重用它而不必知道它的基本查詢細節;
3,使用表的組成部分而不是整個表;
4,保護數據。可以給用戶授予表的特定部分的訪問權限而不是整個表的訪問權限;
5,更改數據格式和表示,視圖可返回與底層表的表示和格式不同的數據;

存儲過程

很多時候,一個完整的操作需要多條語句才能完成,存儲過程就是爲以後的使用而保存的一條或多條mysql語句的集合。並且運行速度快,可將其視爲批文件、函數。

DELIMITER $
CREATE PROCEDURE ordertotal(
    IN onumber INT,
    IN taxable BOOLEAN,
    OUT ototal DECIMAL(8,2)
) COMMENT 'Obtain order total'
BEGIN
    -- Declare variable.
    DECLARE total DECIMAL(8,2);
    DECLARE taxrate INT DEFAULT 6;

    SELECT sum(item_price*quantity)
    FROM orderitems
    WHERE order_num = onumber
    INTO ototal;

    -- Is this taxable?
    IF taxable THEN
        SELECT total+(total/100*taxrate) INTO total;
    END IF;
    SELECT total INTO ototal;
END$
DELIMITER ;

1,關鍵字out表明相應的參數用來從存儲過程中傳出一個值。mysql支持in(傳遞給存儲過程)和out(從存儲過程中傳出)和inout(傳入和傳出)。布爾值0表示假,非零表示真。
2,調用該存儲過程的語句是:call ordertotal(20005,0,@total); 所有的變量都必須以@開始,在調用時,並不顯示任何數據,要想顯示結果,則select @total;
3,存儲過程在創建之後,被保存在服務器上以供使用,直到被刪除。刪除存儲過程的命令如下:drop procedure ordertotal;
4,使用show create procedure name查看存儲過程。
5,DELIMITER $表示臨時修改分割符,因爲存儲過程中用到了;分號。

遊標

使用簡單的select語句,沒有辦法得到第一行、下一行或前10行,也不存在每次一行的處理所有行的簡單方法,有時,需要在檢索出來的行中前進或後退一行或多行,這時就需要使用遊標。
遊標是一個存儲在mysql服務器上的數據庫查詢,它不是一條select語句,而是被該語句檢索出來的結果集。在存儲了遊標之後,應用程序可以根據需要滾動或瀏覽其中的數據。mysql遊標只能用於存儲過程,存儲過程處理完成後,遊標就消失。

CREATE PROCEDURE processorders()
BEGIN
    -- declare local variables
    DECLARE done BOOLEAN DEFAULT 0;
    DECLARE o INT;
    DECLARE t DECIMAL(8,2);

    -- declare the cursor
    DECLARE ordernumbers CURSOR
    FOR
    SELECT order_num FROM orders;

    -- declare continue handler
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1;

    -- createa table to store the results
    CREATE TABLE IF NOT EXISTS ordertotals(order_num INT,
    total DECIMAL(8,2));

    --open the cursor
    OPEN ordernumbers;

    -- loop through all rows
    REPEAT
        -- get order number
        FETCH ordernumbers INTO o;
        -- get the total for this order
        CALL ordertotal(o, 1, t);
        -- insert order and total into ordertotals
        INSERT INTO ordertotals(order_num, total) 
        VALUES(o, t);
    -- end of loop
    UNTIL done END REPEAT;
    --close the cursor
    CLOSE ordernumbers;
END;

1,在使用遊標之前,必須DECLARE聲明定義它。這個過程實際上沒有檢索數據,它只是定義要使用的select語句。
2,一旦聲明之後,必須OPEN打開遊標以供使用。這個過程,會執行前面定義的select語句,並存儲檢索出的數據以供瀏覽和滾動。
3,遊標在打開後,可以使用FETCH語句,分別訪問它的每一行,FETCH還將移動遊標中的內部行指針,使下一條FETCH語句檢索下一行。所以在上例中,FETCH ordernumbers INTO o;表示將檢索當前行的order_num到一個名爲o的局部聲明的變量中。FETCH在REPEAT中,它會反覆執行,直到done爲真。done爲真的條件是:
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done=1; 這條語句定義了一個句柄HANDLER,它在條件出現時被執行,也就是當sqlstate ‘02000’ 出現時,set done = 1。 sqlstate ‘02000’ 表示未找到行,當repeat沒有更多的行而不能繼續循環時,這個條件就會出現。
注意:用declare定義的局部變量必須在定義任意遊標或句柄之前,而句柄必須在遊標之後定義。
4,在結束遊標使用時,必須關閉遊標

觸發器

觸發器是MySQL響應以下任意語句而自動執行的一條MySQL語句(或位於BEGIN和END語句之間的一組語句):DELETE;INSERT;UPDATE。其他的MySQL語句不支持觸發器。只有表才支持觸發器,視圖不支持

創建觸發器需要給出4條信息:
1,唯一的觸發器名;
2,觸發器關聯的表;
3,觸發器應該響應的活動(DELETE、INSERT或UPDATE)
4,觸發器何時執行(處理前還是後,前是BEFORE 後是AFTER)

觸發器按每個表每個事件每次地定義,每個表每個事件每次只允許定義一個觸發器,因此,每個表最多定義6個觸發器(每條INSERT UPDATE 和DELETE的之前和之後)。單個觸發器不能與多個事件或多個表關聯,所以,如果你需要一個對INSERT 和UPDATE存儲執行的觸發器,則應該定義兩個觸發器。

我們建立的數據庫一般都是 InnoDB 數據庫,其上建立的表是事務性表,也就是事務安全的。這時,若SQL語句或觸發器執行失敗,MySQL 會回滾事務,有:
1,如果 BEFORE 觸發器執行失敗,SQL 無法正確執行。
2,SQL 執行失敗時,AFTER 型觸發器不會觸發。
3,AFTER 類型的觸發器執行失敗,SQL 會回滾。

假設系統中有兩個表:
班級表 class(班級號 classID, 班內學生數 stuCount)
學生表 student(學號 stuID, 所屬班級號 classID)
要創建觸發器來使班級表中的班內學生數隨着學生的添加自動更新,代碼如下:

DELIMITER $
CREATE TRIGGER tri_stuInsert AFTER INSERT ON student 
FOR EACH ROW
BEGIN
    DECLARE c INT;
    SET c = (SELECT stuCount FROM class 
    WHERE classID=NEW.classID);
    UPDATE class SET stuCount = c + 1 
    WHERE classID = NEW.classID;
END$
DELIMITER ;

NEW 和 OLD用來表示觸發器的所在表中,觸發了觸發器的那一行數據。NEW表示經過處理後的新表,OLD表示處理前的舊錶。
另外,OLD 是隻讀的,不能更新,而 NEW 則可以在觸發器中使用 SET 賦值,這樣不會再次觸發觸發器。
下面例子時使用OLD保存將要刪除的行到一個存檔表中:

CREATE TRIGGER delete_order BEFORE DELETE ON orders
FOR EACH ROW
BEGIN  
    INSERT INTO archive_orders(order_num, order_date, cust_id)
    VALUES(OLD.order_num, OLD.order_date, OLD.cust_id);
END;

刪除觸發器:DROP TRIGGER name; 觸發器不能更新或覆蓋,所以修改觸發器只能先刪除再創建。
查看觸發器:SHOW TRIGGERS [FROM schema_name];

事務

mysql中,並非所有的引擎都支持事務管理,比如常見的引擎myisam和innodb,前者就不支持事務,而後者支持。事務處理是一種機制,用來管理必須成批執行的mysql操作,以保證數據庫不包含不完整的操作結果。利用事務處理,可以保證一組操作不會中途停止,它們或者作爲整體執行,或者完全不執行。如果沒有錯誤發生,整組語句提交給數據庫表。如果發生錯誤,則進行回退,已恢復數據庫到某個一直且安全的狀態。
事務處理的關鍵詞有
事務(transaction):指一組sql語句;
回退(rollback):撤銷指定sql語句的過程;
提交(commit):將未存儲的sql語句結果寫入數據庫表中;
保留點(savepoint):事務處理中設置的臨時佔位符,可以對他進行回退,而不是回退整個事務。

select * from ordertotals;
start transaction;
delete from ordertotals;
select * from ordertotals;
rollback;
select * from ordertotals;

事務的開始:start transaction;rollback;命令回退。事務處理用來管理insert、update和delete語句,不能回退select(無意義),create和drop操作。

一般的mysql語句都是直接對數據庫表執行和編寫的,這就是所謂的隱含提交,也就是提交操作是自動進行的。但是,在事務處理中,必須使用commit語句進行明確的提交:

start transaction;
delete from orderitems where order_num = 20010;
delete from orders where order_num = 20010;
commit;

事務中的語句全部成功時,commit纔會成功,如果上邊第一條delete起作用,但第二條失敗,則commit不會成功。當commit或rollback語句執行後,事務會自動關閉

對於複雜的事務處理,可能需要部分提交或回退。爲了支持回退部分事務處理,必須能在事務處理塊中合適的位置放置佔位符(保留點)。如果需要回退,可以回退到某個佔位符。使用savepoint語句設置保留點: savepoint delete1;,使用rollback回退到保留點:rollback to delete1;。保留點在事務處理完成(執行commit或rollback)之後自動釋放。

權限

MySQL用戶賬號和信息存儲在名爲mysql的數據庫中,在其中的user表記錄了用戶信息:

USE mysql;
SELECT user FROM user;

1,接下來我們創建一個新用戶賬號,使用CREATE USER語句:CREATE USER gq IDENTIFIED BY '123123';
2,重命名一個用戶賬號,使用RENAME USER語句:RENAME USER gq TO gq2;
3,爲了刪除用戶賬號,使用DROP USER語句:DROP USER gq;
4,新創建的用戶沒有訪問權限,它們只能登陸服務器,但不能看到數據,也不能執行任何數據庫操作。查看用戶賬號的權限,使用:SHOW GRANTS FOR gq;
5,授權GRANT SELECT,INSERT ON test.* TO gq;上述語句允許用戶gq在test .*(test數據庫的所有表)上使用SELECT和INSERT。如果是所有權限用ALL
6,撤銷權限使用revoke語句:REVOKE SELECT ON test.* FROM gq;
7,修改用戶密碼mysqladmin -u 用戶名 -p password 新密碼; 輸入這個命令後,需要輸入用戶名的原密碼。之後,再FLUSH PRIVILEGES;即可生效。
另一種方法是: SET PASSWORD FOR gq = Password('n3wp@$$wOrd'); 這是以root用戶的身份給用gq改密碼,如果用戶gq自己改自己,就去掉FOR gq
還有一種方法是更改本節開頭說的User表。

MySql數據類型

數值型:

整形:
這裏寫圖片描述
上面定義的都是有符號的,當然了,也可以加上unsigned關鍵字,定義成無符號的類型,那麼對應的取值範圍就要翻翻了,比如:tinyint unsigned的取值範圍爲0~255。
浮點型:
這裏寫圖片描述
特別注意浮點型會出現截斷問題,對於float(5, 3)類型:
1,插入123.45678,最後查詢得到的結果爲99.999;
2,插入123.456,最後查詢結果爲99.999;
3,插入12.34567,最後查詢結果爲12.346;

字符串型

這裏寫圖片描述
1,char和varchar最大的區別就在於char不管實際value都會佔用n個字符的空間,而varchar只會佔用實際字符應該佔用的空間+1。
2,超過char和varchar的設置的n後,字符串會被截斷。
3,char在存儲的時候會截斷尾部的空格,varchar和text不會。
4,mysql處理定長比處理變長快很多,而且不能對變長索引。
5,varchar會使用1-3個字節來存儲長度,text不會。

日期時間類型

這裏寫圖片描述

二進制類型

二進制類型可存儲任意數據,如圖像、多媒體、文檔。
這裏寫圖片描述

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