1. 程式人生 > >MySQL 之【視圖】【觸發器】【存儲過程】【函數】【事物】【數據庫鎖】【數據庫備份】

MySQL 之【視圖】【觸發器】【存儲過程】【函數】【事物】【數據庫鎖】【數據庫備份】

單位 說明 bar 大量 sum 字符串拼接 觸發事件 加密 cto

技術分享圖片

視圖:是一個虛擬表,其內容由查詢定義。同真實的表一樣,視圖包含一系列帶有名稱的列和行數據

視圖有如下特點;
  1. 視圖的列可以來自不同的表,是表的抽象和邏輯意義上建立的新關系。
  2. 視圖是由基本表(實表)產生的表(虛表)。
  3. 視圖的建立和刪除不影響基本表。
  4. 對視圖內容的更新(添加、刪除和修改)直接影響基本表。
  5. 當視圖來自多個基本表時,不允許添加和刪除數據。

 1.創建視圖   

create view 視圖名稱  as sql 查詢語句  例子:CREATE view ren_view as SELECT * from ren;

 2.使用視圖

select
* from 視圖名稱; 例子:SELECT * from ren_view;

 3.更新視圖

alter view 視圖名稱 AS SQL語句; 
例子:ALTER view ren_view as SELECT * from ren_view WHERE salary>10000

 4. 刪除視圖

drop view 視圖名稱; 
例子:drop view ren_view

技術分享圖片

觸發器:監視某種情況,並觸發某種操作。

觸發器創建語法四要素:1.監視地點(table)

           2.監視事件(insert/update/delete)

           3.觸發時間(after/before)

           4.觸發事件(insert/update/delete)

1.創建觸發器語法

技術分享圖片

創建兩張表

#商品表

create table goods(

id int primary key auto_increment,

name varchar(20),

num int

);

#訂單表

create table order_table(

oid int primary key auto_increment,

gid int,

much int

);

添加3條商品數

insert into goods(name,num) values(
商品1,10),(商品2,10),(商品3,10);

如果我們在沒使用觸發器之前:假設我們現在賣了3個商品1,我們需要做兩件事

1.往訂單表插入一條記錄

insert into order_table(gid,much) values(1,3);

2.更新商品表商品1的剩余數量

UPDATE goods set num=num-3 WHERE id=1

現在,我們來創建一個觸發器:

create trigger tg1 after insert on  order_table
for each row
begin    
  update goods set num = num -3 where id = 1;
end

這時候我們只要執行:

insert into order_table(gid,much) values(1,3);

會發現商品1的數量變為7了,說明在我們插入一條訂單的時候,

觸發器自動幫我們做了更新操作。

但現在會有一個問題,因為我們觸發器裏面num和id都是寫死的,所以不管我們買哪個商品,最終更新的都是商品1的數量。比如:我們往訂單表再插入一條記錄:

insert into order_table(gid,much) values(2,3);

執行完後會發現商品1的數量變4了,而商品2的數量沒變,這樣顯然不是我們想要的結果。我們需要改改我們之前創建的觸發器。

我們如何在觸發器引用行的值,也就是說我們要得到我們新插入的訂單記錄中的gid或much的值。

對於insert而言,新插入的行用new來表示,行中的每一列的值用new.列名來表示

所以現在我們可以這樣來改我們的觸發器:

CREATE  TRIGGER tg3 after INSERT on order_table for each ROW
BEGIN
    UPDATE goods set num=num-new.much WHERE id=new.gid;

END
 
INSERT into order_table(gid,much) VALUES (3,3)  #相當於啟動觸發器

DROP TRIGGER tg3

執行完發現商品2的數量變為7了,現在就對了。

現在還存在兩種情況:

1.當用戶撤銷一個訂單的時候,我們這邊直接刪除一個訂單,我們是不是需要把對應的商品數量再加回去呢?

對於delete而言:原本有一行,後來被刪除,想引用被刪除的這一行,用old來表示舊表中的值,old.列名可以引用原(舊)表中的值。

那我們的觸發器就該這樣寫:

CREATE trigger tg4 AFTER delete on order_table for each ROW
BEGIN  
 UPDATE goods set num=num+old.much WHERE id=old.gid;

END

DELETE from order_table WHERE gid=2;
DROP TRIGGER tg4

2.當用戶修改一個訂單的數量時,我們觸發器修改怎麽寫?

CREATE TRIGGER tg5 after UPDATE on order_table for each ROW
BEGIN 
 UPDATE goods set num=num+old.much-new.much WHERE id=new.gid;
END

UPDATE order_table set much=much-2 WHERE oid=1
DROP TRIGGER tg5;

技術分享圖片

MySQL數據庫在5.0版本後開始支持存儲過程,那麽什麽是存儲過程呢?怎麽創建、查看和刪除存儲過程呢?存儲過程有什麽優點?

 存儲過程類似於函數(方法),簡單的說存儲過程是為了完成某個數據庫中的特定功能而編寫的語句集合,該語句集包括SQL語句(對數據的增刪改查)、條件語句和循環語句等。

1. 查看現有的存儲過程

show procedure status;

2 .刪除存儲過程

drop procedure 存儲過程名稱;

3. 調用 存儲過程

call 存儲過程名稱(參數入/出類型 參數名 數據類型);

4.創建存儲過程

1.體會封裝
CREATE PROCEDURE p1()
BEGIN
    SELECT * FROM ren;
END

cALL P1; 調用存儲過程
2.SQL 體會參數
-- CREATE procedure p1(in i int,in c char(10))
-- BEGIN
--     if c=a then 
--     SELECT * from ren WHERE age>i;
--  ELSE SELECT * from ren WHERE age<i;
--     end if;
-- END
-- 
--  set @i = 30; 
-- CALL p1(@i,d)
-- 
-- DROP PROCEDURE p1

4.體會循環:計算1-100累加的和,並且返回計算結果.

CREATE procedure p2(inout n int)
BEGIN
DECLARE sum int DEFAULT 0; -- 設置總和變量,並且指定初始值0
DECLARE i int; -- 聲明變量
set i = 0; -- 通過set為變量設置值
WHILE i<=n DO -- 開始循環
set sum = sum +i;
set i = i +1;
END WHILE; -- 結束循環
SELECT sum; -- 提供結果
set n=sum; --將計算結果提供給 輸出變量 n;
END

set @n=100;
call p2(@n); #調用
SELECT @n

存儲過程優點
1、存儲過程增強了SQL語言靈活性。

      存儲過程可以使用控制語句編寫,可以完成復雜的判斷和較復雜的運算,有很強的靈活性;
2、減少網絡流量,降低了網絡負載。

      存儲過程在服務器端創建成功後,只需要調用該存儲過程即可,而傳統的做法是每次都將大量的SQL語句通過網絡發送至數據庫服務器端然後再執行
3、存儲過程只在創造時進行編譯,以後每次執行存儲過程都不需再重新編譯。

      一般SQL語句每執行一次就編譯一次,所以使用存儲過程可提高數據庫執行速度。
存儲過程缺點

   1、擴展功能不方便

   2、不便於系統後期維護

技術分享圖片

MySQL提供的內建函數:

技術分享圖片
一、數學函數
    ROUND(x,y)
        返回參數x的四舍五入的有y位小數的值
        
    RAND()
        返回0到1內的隨機值,可以通過提供一個參數(種子)使RAND()隨機數生成器生成一個指定的值。

二、聚合函數(常用於GROUP BY從句的SELECT查詢中)
    AVG(col)返回指定列的平均值
    COUNT(col)返回指定列中非NULL值的個數
    MIN(col)返回指定列的最小值
    MAX(col)返回指定列的最大值
    SUM(col)返回指定列的所有值之和
    GROUP_CONCAT(col) 返回由屬於一組的列值連接組合而成的結果    
    
三、字符串函數

    CHAR_LENGTH(str)
        返回值為字符串str 的長度,長度的單位為字符。一個多字節字符算作一個單字符。
    CONCAT(str1,str2,...)
        字符串拼接
        如有任何一個參數為NULL ,則返回值為 NULL。
    CONCAT_WS(separator,str1,str2,...)
        字符串拼接(自定義連接符)
        CONCAT_WS()不會忽略任何空字符串。 (然而會忽略所有的 NULL)。

    FORMAT(X,D)
        將數字X 的格式寫為#,###,###.##,以四舍五入的方式保留小數點後 D 位, 並將結果以字符串的形式返回。若  D 為 0, 則返回結果不帶有小數點,或不含小數部分。
        例如:
            SELECT FORMAT(12332.1,4); 結果為: 12,332.1000
    
    INSERT(str,pos,len,newstr)
        在str的指定位置插入字符串
            pos:要替換位置其實位置
            len:替換的長度
            newstr:新字符串
        例如:
            SELECT INSERT(abcd,1,2,tt); 結果為: ttcd
            SELECT INSERT(abcd,1,4,tt); 結果為: tt
        特別的:
            如果pos超過原字符串長度,則返回原字符串
            如果len超過原字符串長度,則由新字符串完全替換
    
    INSTR(str,substr)
        返回字符串 str 中子字符串的第一個出現位置。

    LEFT(str,len)
        返回字符串str 從開始的len位置的子序列字符。
        例如:
            SELECT INSTR(abc,c); 結果為: 3
            SELECT INSTR(abc,d); 結果為: 0
            
    LOWER(str)
        變小寫

    UPPER(str)
        變大寫
   
    REVERSE(str)
        返回字符串 str ,順序和字符順序相反。
        例如:
            SELECT REVERSE(1234567) 結果為:7654321
            
    SUBSTRING(str,pos) , SUBSTRING(str FROM pos) SUBSTRING(str,pos,len) , SUBSTRING(str FROM pos FOR len)
        不帶有len 參數的格式從字符串str返回一個子字符串,起始於位置 pos。帶有len參數的格式從字符串str返回一個長度同len字符相同的子字符串,起始於位置 pos。 使用 FROM的格式為標準 SQL 語法。也可能對pos使用一個負值。假若這樣,則子字符串的位置起始於字符串結尾的pos 字符,而不是字符串的開頭位置。在以下格式的函數中可以對pos 使用一個負值。

        mysql> SELECT SUBSTRING(Quadratically,5); -- 從第5位開始截取
            -> ratically

        mysql> SELECT SUBSTRING(foobarbar FROM 4); -- 從第4位開始截取
            -> barbar

        mysql> SELECT SUBSTRING(Quadratically,5,6); --從第5位開始截取,截取6個長度
            -> ratica

        mysql> SELECT SUBSTRING(Sakila, -3);    -- 從倒數第3位開始截取
            -> ila

        mysql> SELECT SUBSTRING(Sakila, -5, 3); -- 從倒數第5位開始截取,截取3個長度
            -> aki
            
四、日期和時間函數
    CURDATE()或CURRENT_DATE() 返回當前的日期
    CURTIME()或CURRENT_TIME() 返回當前的時間
    DAYOFWEEK(date)   返回date所代表的一星期中的第幾天(1~7)
    DAYOFMONTH(date)  返回date是一個月的第幾天(1~31)
    DAYOFYEAR(date)   返回date是一年的第幾天(1~366)
    DAYNAME(date)   返回date的星期名,如:SELECT DAYNAME(CURRENT_DATE);
    FROM_UNIXTIME(ts,fmt)  根據指定的fmt格式,格式化UNIX時間戳ts
    HOUR(time)   返回time的小時值(0~23)
    MINUTE(time)   返回time的分鐘值(0~59)
    MONTH(date)   返回date的月份值(1~12)
    MONTHNAME(date)   返回date的月份名,如:SELECT MONTHNAME(CURRENT_DATE);
    NOW()    返回當前的日期和時間
    QUARTER(date)   返回date在一年中的季度(1~4),如SELECT QUARTER(CURRENT_DATE);
    WEEK(date)   返回日期date為一年中第幾周(0~53)
    YEAR(date)   返回日期date的年份(1000~9999)
    
    重點:
    DATE_FORMAT(date,format) 根據format字符串格式化date值

       mysql> SELECT DATE_FORMAT(2009-10-04 22:23:00, %W %M %Y);
        -> Sunday October 2009
       mysql> SELECT DATE_FORMAT(2007-10-04 22:23:00, %H:%i:%s);
        -> 22:23:00
       mysql> SELECT DATE_FORMAT(1900-10-04 22:23:00,
        ->                 %D %y %a %d %m %b %j);
        -> 4th 00 Thu 04 10 Oct 277
       mysql> SELECT DATE_FORMAT(1997-10-04 22:23:00,
        ->                 %H %k %I %r %T %S %w);
        -> 22 22 10 10:23:00 PM 22:23:00 00 6
       mysql> SELECT DATE_FORMAT(1999-01-01, %X %V);
        -> 1998 52
       mysql> SELECT DATE_FORMAT(2006-06-00, %d);
        -> 00
        
五、加密函數
    MD5()    
        計算字符串str的MD5校驗和
        例如:
            SELECT MD5(1234) 結果為:81dc9bdb52d04dc20036dbd8313ed055
    PASSWORD(str)   
        返回字符串str的加密版本,這個加密過程是不可逆轉的
        例如:
            SELECT PASSWORD(1234) 結果為:*A4B6157319038724E3560894F7F932C8886EBFCF
        
六、控制流函數            
    CASE WHEN[test1] THEN [result1]...ELSE [default] END
        如果testN是真,則返回resultN,否則返回default
    CASE [test] WHEN[val1] THEN [result]...ELSE [default]END  
        如果test和valN相等,則返回resultN,否則返回default

    IF(test,t,f)   
        如果test是真,返回t;否則返回f

    IFNULL(arg1,arg2) 
        如果arg1不是空,返回arg1,否則返回arg2
        例如:
            SELECT IFNULL(bbb,abc); 結果為: bbb
            SELECT IFNULL(null,abc);  結果為: abc

    NULLIF(arg1,arg2) 
        如果arg1=arg2返回NULL;否則返回arg1
        例如:
            SELECT NULLIF(bbb,bbb);結果為: null
            SELECT NULLIF(aaa,bbb);結果為: aaa
MySQL內建函數

更多函數: 官方猛擊這裏

1、自定義函數

CREATE FUNCTION fun1(i1 int,i2 int)
RETURNS INT //設置返回類型
BEGIN
    DECLARE sum int default 0;
    set sum = i1+i2;
    RETURN(sum); //返回結果
end

2.調用自定義函數

#直接調用自定義函數
select fun1(1,5);
#在sql語句中使用自定義函數
select fun1(參數1,參數2),name from 表名

3.刪除自定義函數

DROP FUNCTION fun_name;

MySQL 之【視圖】【觸發器】【存儲過程】【函數】【事物】【數據庫鎖】【數據庫備份】