視圖,存儲過程,觸發器

1、視圖javascript

一、視圖的定義java

  視圖是由查詢結果造成的一張虛擬表,是表經過某種運算獲得的一個投影。mysql

  同一張表能夠建立多個視圖算法

  建立視圖的語法:  sql

?
1
create view view_name as select 語句

  說明:數據庫

  (1)視圖名跟表名是一個級別的名字,隸屬於數據庫;編程

  (2)該語句的含義能夠理解爲:就是將該select命名爲該名字(視圖名);安全

  (3)視圖也能夠設定本身的字段名,而不是select語句自己的字段名——一般不設置;服務器

  (4)視圖的使用,幾乎跟表同樣!編程語言

二、視圖的做用

2.一、能夠簡化查詢

  案例一:查詢平均價格前3高的類目

  傳統的sql語句寫法:select cat_id,avg(price) as pj from goods group by cat_id order by pj desc limit 3;

  下面建立一個視圖,簡化查詢。

  語法:create view goods_v as select cat_id,avg(price) as pj from goods group by cat_id;

  查詢平均價格前3高的欄目,咱們只需查詢視圖便可,以下圖:

  案例二:查詢出商品表,以及所在的類目名稱

  傳統寫法:select a.id as goods_id,goods_name,cat_name,price from goods as a left join category as b on a.cat_id=b.id;

  建立視圖:create view goods_v2 as select a.id as goods_id,goods_name,cat_name,price from goods as a left join category as b on a.cat_id=b.id;

  查詢視圖:select * from goods_v2;

2.二、能夠進行權限控制

  把表的權限封閉,可是開放相應的視圖權限,視圖裏只開放部分數據,好比某張表,用戶表爲例,2個網站搞合做,能夠查詢對方網站的用戶,須要向對方開放用戶表的權限,可是呢,又不想開放用戶表中的密碼字段。

  再好比一個goods表,兩個網站搞合做,能夠相互查詢對方的商品表,好比進貨價格字段不能讓對方查看。

  第一步:建立一個視圖,視圖中不能包含in_price字段。

  語法: create view goods_v1 as select id,goods_name,shop_price from goods;

  第二步:建立一個用戶,授予查詢權限,只能操做goods_v1表(視圖)。

  語法:grant select on db1.goods_v1 to 'xiaotian'@'%' identified by '1234456';

三、查詢視圖

  語法:select * from 視圖名 [where 條件]

  視圖和表同樣,能夠添加where 條件!

四、修改視圖

  alter view view_name as select XXXX;

五、刪除視圖

  drop view 視圖名稱;

六、查看視圖結構

  和表同樣的,語法:desc 視圖名稱;

七、查看全部視圖

  和表同樣,語法:show tables;

  注意:沒有show views語句!

 

八、視圖與表的關係

  視圖是表的查詢結果,天然表的數據改變了,影響視圖的結果。

8.一、視圖的數據與表的數據一一對應時,能夠修改。

  可見,對視圖的修改,也會影響到數據庫表的修改。

8.二、視圖增刪改也會影響表,可是視圖並非老是能增刪改的。

  注意:視圖的數據與表的數據一一對應時,能夠修改。

8.三、對於視圖insert還應注意,視圖必須包含表中沒有默認值的列。

  以上對user_v1的操做,就相似於,以下sql語句的操做,緣由就是age字段沒有默認值,咱們insert語句中沒有包含age字段:

create table user(
    id int not null,
    name varchar(32) not null,
    age tinyint not null
)engine myisam charset utf8;

insert into user values(5,'xiaoshuang');
SQL語句

  注意:通常來講,視圖只是用來查詢的,不該該執行增刪改的操做。

九、視圖算法(algorithm= merge/temptable/undefined)

  merge:當引用視圖時,引用視圖的語句與定義視圖的語句合併(默認)。

  temptable:當引用視圖時,根據視圖的建立語句創建一個臨時表。

  undefined:未定義,自動讓系統幫你選。

  merge:意味着,視圖只是一個語句規則,當查詢視圖時,把查詢視圖的語句(好比where那些)與建立時的語句where子句等合併,分析,造成一條 select語句。

  temptable:是根據建立語句瞬間建立一張臨時表,而後查詢視圖的語句,從該臨時表查數據。

  好比以下視圖的算法爲merge:

  # 在建立視圖時的語句:where shop_price>1000;

  # 查詢視圖時,where shop_price<3000;

  # 那麼查此視圖時,真正發生的是where (select where) and (view where)

  # where shop_price <3000 and shop_price >1000;

  # 分析出最終語句仍是去查goods表

2、SQL編程

一、變量聲明

1.一、會話變量

  定義形式:set @變量名 = 值;

  說明:

  1,第一次給其賦值,就算定義了。

  2,它能夠在編程環境和非編程環境中使用。

  3,使用的任何場合也都帶該"@"符號。

1.二、普通變量

  定義形式:declare 變量名 類型 【default 默認值】;

  說明:

  一、它必須先聲明(即定義),此時也能夠賦值。

  二、賦值跟會話變量同樣: set 變量名 = 值。

  三、它只能在編程環境中使用!!!

  說明:什麼是編程環境?

  存儲過程,函數,觸發器就是編程環境。

1.三、變量賦值形式

  語法一:

    set 變量名 = 表達式;                 # 此語法中的變量必須先使用declare聲明

  語法二:

    set @變量名=表達式;            # 此方式能夠無需declare語法聲明,而是直接賦值。

  語法三:

   select @變量名:=表達式;           # 此語句會給該變量賦值,同時還會做爲一個select語句輸出'結果集'。

  語法四:

    select 表達式 into @變量名;          # 此語句雖然看起來是select語句,但其實並不輸出'結果集',而是給變量賦值。

 

二、運算符

2.一、算術運算符

  +、-、*、/、%

  注意:mysql沒有++和—運算符

2.二、關係運算符

  >、>=、<、<=、=(等於)、<>(不等於)、!=(不等於)

2.三、邏輯運算符

  and(與)、or(或)、not(非)

三、語句塊包含符

  所謂語句塊包含符,在js以及絕大部分的其餘語言中,都是大括號:{}

  它用在不少場合:if,switch,for,function

  而mysql編程中的語句塊包含符是:

四、if判斷

  MySQL支持兩種判斷,第一個是if判斷,第二個 case判斷。

  單分支

if 條件 then
    // 代碼
end if;

  雙分支

if 條件 then
    // 代碼1
else
    // 代碼2
end if;

  多分支

複製代碼
if 條件 then
    // 代碼1
elseif 條件 then
    // 代碼2
else
    // 代碼3
end if;
複製代碼

  案例:接收4個數字,若是輸入1則輸出春天,2=》夏天,3=》秋天,4 =》冬天,其餘數字=》出錯

  咱們使用存儲過程來體驗if語句的用法,

  create procedure 存儲過程名(參數,參數,…)

  begin

      // 代碼

  end

  注意:一般狀況下,";"表示SQL語句結束,同時向服務器提交併執行。可是存儲過程當中有不少SQL語句,每一句都要以分號隔開,這時候咱們就須要使用其餘符號來代替向服務器提交的命令。經過delimiter命令更改語句結束符。

  具體的語句以下:

  調用語法:call 存儲過程的名稱(參數)

五、case判斷

case 變量
when 值 then 語句;
when 值 then 語句;
else 語句;
end case ;

  案例:接收4個數字,若是輸入1則輸出春天,2=》夏天,3=》秋天,4 =》冬天,其餘數字=》出錯

  具體語法:

  調用:

 

六、循環

  MySQL支持的循環有loop、while、repeat循環。

6.一、loop循環

標籤名:loop
    leave 標籤名;       -- 退出循環
end loop;

6.二、while循環

[標籤:]while 條件 do
    // 代碼
end while;

6.三、repeat循環

repeat
    // 代碼
until 條件 end repeat;

3、存儲過程

一、概念

  存儲過程(procedure):相似於函數,就是把一段代碼封裝起來,當要執行這一段代碼的時候,能夠經過調用該存儲過程來實現。

  在封裝的語句體裏面,能夠用if/else,case,while等控制結構,能夠進行sql編程。

  查看現有的存儲過程:

  show procedure status

二、存儲過程的優勢

  存儲過程(Stored Procedure)是在大型數據庫系統中,一組爲了完成特定功能的SQL 語句集,存儲在數據庫中,通過第一次編譯後再次調用不須要再次編譯,用戶經過指定存儲過程的名字並給出參數(若是該存儲過程帶有參數)來執行它。存儲過程是數據庫中的一個重要對象,任何一個設計良好的數據庫應用程序都應該用到存儲過程。

(1)存儲過程只在創造時進行編譯,之後每次執行存儲過程都不需再從新編譯,而通常SQL語句每執行一次就編譯一次,因此使用存儲過程可提升數據庫執行速度。

(2)當對數據庫進行復雜操做時(如對多個表進行Update,Insert,Query,Delete時),可將此複雜操做用存儲過程封裝起來與數據庫提供的事務處理結合一塊兒使用。

(3)存儲過程能夠重複使用,可減小數據庫開發人員的工做量。

(4)安全性高,可設定只有某些用戶才具備對指定存儲過程的使用權。

三、建立存儲過程

create procedure 存儲過程名(參數,參數,…)
begin
    // 代碼
end

  存儲過程的參數分爲輸入參數(in)、輸出參數(out)、輸入輸出參數(inout),默認是輸入參數。

  若是存儲過程當中就一條語句,begin和end是能夠省略的。

  說明:

  (1)存儲過程當中,可有各類編程元素:變量,流程控制,函數調用;

  (2)還能夠有:增刪改查等各類mysql語句;

  (3)其中select(或show,或desc)會做爲存儲過程執行後的"結果集"返回;

  (4)形參能夠設定數據的"進出方向";

  案例一:查詢一個表裏面某些語句

  調用結果:

 

  案例二(體會參數):輸入一個字符串,若是等於h則取出價格大於1000的商品,輸入其餘的值,則輸出小於1000的商品。

  調用結果:

四、調用存儲過程

  語法:call 存儲過程名稱()

  mysql_query("call 存儲過程名稱()")

五、刪除存儲過程

  語法:drop procedure [if exists] 存儲過程名

六、建立複雜的存儲過程

  案例一:體會循環,計算1到n的和

  案例二:帶輸出參數的存儲過程

  案例三:帶有輸入輸出參數的存儲過程

 

七、declare聲明局部變量

  在編程環境中使用。

  用戶變量只要在前面加一個@符便可:

  set @name='李白';

  select @name;

  通俗理解術語之間的區別:

    用戶定義的變量就叫用戶變量。這樣理解的話,會話變量和全局變量均可以是用戶定義的變量。只是他們是對當前客戶端生效仍是對全部客戶端生效的區別了。因此,用戶變量包括了會話變量和全局變量。

    局部變量與用戶變量的區分在於兩點:

      1)用戶變量是以」@」開頭的。局部變量沒有這個符號。

      2)定義變量不一樣。用戶變量使用set語句,局部變量使用declare語句定義。

      3)做用範圍。局部變量只在begin-end語句塊之間有效。在begin-end語句塊運行完以後,局部變量就消失了。

  變量包括局部變量和用戶變量。用戶變量包括會話變量和全局變量。

八、系統變量

  MySQL啓動的時候就存在的變量,以@@開頭的都是系統變量。

4、函數

一、自定義函數

  它跟js中的函數幾乎同樣:須要先定義,而後調用(使用)。

  只是規定,這個函數,必需要返回數據——即要有返回值。

1.一、定義語法

create function 函數名(參數 參數的類型) returns 返回值類型
begin
    // 代碼
end

  說明:

  (1)函數內部能夠有各類編程語言的元素:變量,流程控制,函數調用;

  (2)函數內部能夠有增刪改等語句!

  (3)但:函數內部不能夠有select(或show或desc)這種返回結果集的語句!

1.二、調用

  跟系統函數調用同樣:任何須要數據的位置,均可以調用該函數。

  案例一:返回兩個數的和

  案例二:定義一個函數,返回1到n的和

  注意:建立的函數,是隸屬於數據庫的,只能在建立函數的數據庫中使用。

二、系統函數

2.一、數字類

mysql> select rand();        -- 返回0到1間的隨機數
mysql>select * from goods order by rand() limit 2;        -- 隨機取出2件商品
mysql>select floor(3.9);        -- 輸出3  地板數
mysql>select ceil(3.1);         -- 輸出4  天花板數
mysql>select round(3.5);        -- 輸出4  四捨五入

2.二、大小寫轉換

mysql> select ucase('I am a girl!')      -- 轉成大寫
mysql> select lcase('I am a girl!')      -- 轉成小寫

2.三、截取字符串

mysql> select left('abcde',3)            -- 從左邊截取
mysql> select right('abcde',3)           -- 從右邊截取
mysql> select substring('abcde',2,3)     -- 從第二個位置開始,截取3個,注意:位置從1開始
mysql> select concat(10,':鋤禾日當午')     -- 字符串相連

複製代碼
mysql> select coalesce(null,123);
coalesce(str1,str2):   -- 若是第str1爲null,就顯示str2
mysql> select stuname,stusex,coalesce(writtenexam,'缺考'), coalesce(labexam,'缺考') from stuinfo natural left join stumarks
mysql> select length('鋤禾日當午') -- 輸出10 顯示字節的個數
mysql> select char_length('鋤禾日當午') -- 輸出5 顯示字符的個數
mysql> select length(trim(' abc ')) -- trim用來去字符串兩邊空格
mysql> select replace('abc','bc','pache')-- 將bc替換成pache
複製代碼

2.四、時間類

mysql> select unix_timestamp()    -- 時間戳

mysql> select from_unixtime(unix_timestamp())    -- 將時間戳轉成日期格式

mysql> select curdate()   -- 返回今天的時間日期

mysql> select now()      -- 取出當前時間

mysql> select year(now()),month(now()),day(now()),hour(now()),minute(now()),second(now())        -- 年月日時分秒

mysql>select datediff(now(),'1997-7-1')    -- 兩個日期相距多少天

mysql> select concat(10,if(10%2=0,'偶數','奇數'))    -- if(表達式,值1,值2):相似於三元運算符

  案例一:好比一個電影網站,求出今天添加的電影;在添加電影時,有一個添加的時間戳。

  思路:

  curdate()求出今天的日期

  把添加的時間戳,轉換成日期

  案例二:好比一個電影網站,求出昨天添加的電影;在添加電影時,有一個添加的時間戳。

  思路:把添加的時間戳,轉換成日期,和昨天的日期比較。

  問題:如何求出昨天的日期?

  date_sub和date_add函數

  基本用法:date_sub(時間日期時間,interval 數字 時間單位)

  說明:

  (1)時間單位:能夠是year month day hour minute second

  (2)數字:能夠是正數和負數

  好比:取出昨天的日期

select date_sub(curdate(),interval 1 day)
或
select date_add(curdate(),interval -1 day)

  好比:取出前天的日期

select date_sub(curdate(),interval 2 day)
或
select date_add(curdate(),interval -2 day)

  好比:取出後天的日期

select date_sub(curdate(),interval -1 day)
或
select date_add(curdate(),interval 1 day)

  迴歸案例:好比一個電影網站,求出9天前添加的電影;在添加電影時,有一個添加的時間戳。

5、觸發器

一、簡介

(1)觸發器是一個特殊的存儲過程,它是MySQL在insert、update、delete的時候自動執行的代碼塊。

(2)觸發器必須定義在特定的表上。

(3)自動執行,不能直接調用。

  做用:監視某種狀況並觸發某種操做。

  觸發器的思路:

  監視it_order表,若是it_order表裏面有增刪改的操做,則自動觸發it_goods裏面裏面增刪改的操做。

  好比新添加一個訂單,則it_goods表,就自動減小對應商品的庫存。

  好比取消一個訂單,則it_goods表,就自動增長對應商品的庫存減小的庫存。

二、觸發器四要素

三、建立觸發器

  語法:

複製代碼
create trigger trigger_name
after/before insert/update/delete on 表名
for each row
begin
sql語句:(觸發的語句一句或多句)
end
複製代碼

  案例一:第一個觸發器,購買一個饅頭,減小1個庫存

  分析:

    監視的地點: it_order表。

    監視的事件: it_order表的insert操做。

    觸發的時間: it_order表的insert以後。

    觸發的事件:it_goods表減小庫存的操做。

  測試效果以下:

  上面咱們建立的觸發器t1是有問題,咱們購買任何商品都是減小饅頭的庫存。

  案例二:購買商品,減小對應庫存

複製代碼
create trigger t2
after insert on it_order
for each row
begin
update it_goods set goods_number=goods_number-new.much where id=new.goods_id;
end$ 
複製代碼

  注意:若是在觸發器中引用行的值。

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

  測試效果以下:

相關文章
相關標籤/搜索