MySQL 拓展

MySQL 拓展

視圖

本身是一個虛擬表,它的數據來自於表,通過執行時動態生成,佔用較小,只保存了sql邏輯,不保存查詢結果。臨時表

場景:多個地方用到同樣的查詢結果;該查詢結果使用的sql語句較複雜

create view 視圖名
as
查詢語句;

create or replace view 視圖名
as
查詢語句;
alter view 視圖名
as
查詢語句

drop view 視圖1,視圖2,...;

desc 視圖名;
show create view 視圖名;
CREATE VIEW my_v1
AS
SELECT studentname,majorname
FROM student s
INNER JOIN major m
ON s.majorid=m.majorid
WHERE s.majorid=1;

注意:視圖一般用於查詢的,而不是更新的,所以具備以下特點的視圖都不允許更新

  1. 包含分組函數、group by、distinct、having、union、
  2. join
  3. 常量視圖
  4. where 後的子查詢用到了 from 中的表
  5. 用到了不可更新的視圖

變量

系統變量

變量由系統提供的,不用自定義

全局變量:服務器層面上的,必須擁有super權限才能爲系統變量賦值,作用域爲整個服務器,也就是針對於所有連接(會話)有效

查看所有全局變量
SHOW GLOBAL VARIABLES;
查看滿足條件的部分系統變量
SHOW GLOBAL VARIABLES LIKE '%char%';
查看指定的系統變量的值
SELECT @@global.autocommit;
爲某個系統變量賦值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;

會話變量:服務器爲每一個連接的客戶端都提供了系統變量,作用域爲當前的連接(會話)

查看所有會話變量
SHOW SESSION VARIABLES;
查看滿足條件的部分會話變量
SHOW SESSION VARIABLES LIKE '%char%';
查看指定的會話變量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;
爲某個會話變量賦值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';

如果沒有顯式聲明 global 還是 session,則默認是 session

自定義變量

用戶變量

  • 作用域:針對於當前連接(會話)生效
  • 位置:begin end裏面,也可以放在外面
①聲明並賦值:
set @變量名=;set @變量名:=;select @變量名:=;

②更新值
方式一:
	set @變量名=;set @變量名:=;select @變量名:=;
方式二:
	select xx into @變量名 from;

③使用
select @變量名;

局部變量

  • 作用域:僅僅在定義它的 begin end中有效
  • 位置:只能放在 begin end中,而且只能放在第一句
①聲明
declare 變量名 類型 【default 值】;
②賦值或更新
方式一:
	set 變量名=;set 變量名:=;select @變量名:=;
方式二:
	select xx into 變量名 from;
③使用
select 變量名;
作用域 定義位置 語法
用戶變量 當前會話 會話的任何地方 加@符號,不用指定類型
局部變量 定義它的BEGIN END中 BEGIN END的第一句話 一般不用加@,需要指定類型

數據庫存儲過程

數據庫存儲過程:就是一組SQL語句集,功能強大,可以實現一些比較複雜的邏輯功能,類似於JAVA語言中的方法。

存儲過程跟觸發器有點類似,都是一組SQL集,但是存儲過程是主動調用的,且功能比觸發器更加強大,觸發器是某件事觸發後自動調用;

創建

create procedure 存儲過程名(參數模式 參數名 參數類型)
begin
		存儲過程體
end

注意

  1. 參數模式:in、out、inout,其中in可以省略
  2. 存儲過程體的每一條sql語句都需要用分號結尾
  3. in、out、inout都可以在一個存儲過程中帶多個

結束標記

使用 delimiter 指定新的結束標記

delimiter $

調用

call 存儲過程名(實參列表)
舉例:
調用in模式的參數:call sp1(‘值’);
調用out模式的參數:set @name; call sp1(@name);select @name;
調用inout模式的參數:set @name=; call sp1(@name); select @name;

查看

show create procedure 存儲過程名;

刪除

drop procedure 存儲過程名;

下面創建一個名爲num_from_employee的存儲過程.

CREATE PROCEDURE num_from_employee (IN emp_id INT, OUT count_num INT ) 
     READS SQL DATA 
     BEGIN 
       SELECT COUNT(*) INTO count_num 
       FROM employee 
       WHERE d_id=emp_id ; 
     END
     
#調用
SET @cnum ; # 不定義直接用也可以
CALL num_from_employee(123,@cnum);

存儲過程名稱爲 num_from_employee;輸入變量爲emp_id;輸出變量爲count_num。SELECT語句從employee表查詢d_id值等於emp_id的記錄,並用COUNT(*)計算d_id值相同的記錄的條數,最後將計算結果存入count_num中。

函數

創建

create function 函數名(參數名 參數類型) returns  返回類型
begin
	函數體
end

注意:函數體中肯定需要有return語句

#案例1:根據員工名,返回它的工資;有參有返回
CREATE FUNCTION myf2(empName VARCHAR(20)) RETURNS DOUBLE
BEGIN
	SET @sal=0;#定義用戶變量 
	SELECT salary INTO @sal   #賦值
	FROM employees
	WHERE last_name = empName;	
	RETURN @sal;
END $

SELECT myf2('k_ing') $

調用

select 函數名(實參列表);

查看

show create function 函數名;

刪除

drop function 函數名;
關鍵字 調用語法 返回值 應用場景
函數 FUNCTION SELECT 函數() 只能是一個 一般用於查詢結果爲一個值並返回時
存儲過程 PROCEDURE CALL 存儲過程() 可以有0個或多個 一般用於更新

流程控制

順序結構:程序從上往下依次執行

分支結構:程序按條件進行選擇執行,從兩條或多條路徑中選擇一條執行

循環結構:程序滿足一定條件下,重複執行一組語句

分支結構

if 函數

  • 功能:實現簡單雙分支
  • 語法:if(條件,值1,值2)
  • 位置:可以作爲表達式放在任何位置

case 結構

  • 功能:實現多分支
  • 位置:可以放在任何位置,
    • 如果放在begin end 外面,作爲表達式結合着其他語句使用
    • 如果放在begin end 裏面,一般作爲獨立的語句使用
語法1case 表達式或字段
when1 then 語句1;
when2 then 語句2..
else 語句n;
end [case];

語法2case 
when 條件1 then 語句1;
when 條件2 then 語句2..
else 語句n;
end [case];

if 結構

  • 功能:實現多分支
  • 位置:只能放在begin end中
if 條件1 then 語句1;
elseif 條件2 then 語句2;
...
else 語句n;
end if;

循環結構

while

名稱可以不寫,寫了就成對使用,記得冒號

【名稱:】while 循環條件 do
		循環體
end while 【名稱】;

loop

注意死循環

【名稱:】loop
		循環體
end loop 【名稱】;

repeat

【名稱:】repeat
		循環體
until 結束條件 
end repeat 【名稱】;

比較

位置:只能放在begin end中

特點:都能實現循環結構

對比:

  • 這三種循環都可以省略名稱,但如果循環中添加了循環控制語句(leave或iterate)則必須添加名稱
  • loop 一般用於實現簡單的死循環
  • while 先判斷後執行
  • repeat 先執行後判斷,無條件至少執行一次

循環控制語句

  • leave:類似於break,用於跳出所在的循環
  • iterate:類似於continue,用於結束本次循環,繼續下一次
/*一、已知表stringcontent
其中字段:
id 自增長
content varchar(20)

向該表插入指定個數的,隨機的字符串
*/
DROP TABLE IF EXISTS stringcontent;
CREATE TABLE stringcontent(
	id INT PRIMARY KEY AUTO_INCREMENT,
	content VARCHAR(20)
	
);
DELIMITER $
CREATE PROCEDURE test_randstr_insert(IN insertCount INT)
BEGIN
	DECLARE i INT DEFAULT 1;
	DECLARE str VARCHAR(26) DEFAULT 'abcdefghijklmnopqrstuvwxyz';
	DECLARE startIndex INT;#代表初始索引
	DECLARE len INT;#代表截取的字符長度
	WHILE i<=insertcount DO
		SET startIndex=FLOOR(RAND()*26+1);#代表初始索引,隨機範圍1-26
		SET len=FLOOR(RAND()*(20-startIndex+1)+1);#代表截取長度,隨機範圍1-(20-startIndex+1)
		INSERT INTO stringcontent(content) VALUES(SUBSTR(str,startIndex,len));
		SET i=i+1;
	END WHILE;

END $

CALL test_randstr_insert(10)$

觸發器

觸發器(TRIGGER)是由事件來觸發某個操作。這些事件包括INSERT語句、UPDATE語句和DELETE語句。當數據庫系統執行這些事件時,會激活促發其執行相應的操作。參考

CREATE TRIGGER 觸發器名 BEFORE|AFTER 觸發事件
ON 表名 FOR EACH ROW
BEGIN
    執行語句列表
END

觸發事件

  • INSERT 型觸發語句:INSERT,LOAD DATA,REPLACE
  • UPDATE 型觸發語句:UPDATE
  • DELETE 型觸發語句:DELETE,REPLACE

當在users中插入一條數據,就會在logs中生成一條日誌信息。

DELIMITER $
CREATE TRIGGER user_log AFTER INSERT ON users FOR EACH ROW
BEGIN
    DECLARE s1 VARCHAR(40)character set utf8;
    DECLARE s2 VARCHAR(20) character set utf8;#後面發現中文字符編碼出現亂碼,這裏設置字符集
    SET s2 = " is created";
    SET s1 = CONCAT(NEW.name,s2);     #函數CONCAT可以將字符串連接
    INSERT INTO logs(log) values(s1);
END $
DELIMITER ;

定時任務

mysql5.1.6 增加了一個事件調度器(Event Scheduler),可以做定時任務(定時刪除記錄,定時數據統計),取代之前系統的計劃任務。mysql事件調度器可以精確到每秒執行一個任務。參考

事件調度器與觸發器的區別:事件調度器是基於特定時間週期來觸發執行某些任務,觸發器是基於某個表產生的事件來觸發。

查看是否開啓

show variables like 'event_scheduler';

開啓事件調度器

set global event_scheduler = on;

當mysql重啓後,會自動關閉。如果需要一直開啓,需要在my.ini中配置如下:event_scheduler = on

創建事件語法

CREATE EVENT [IF NOT EXISTS ] event_name
ON SCHEDULE schedule
[ ON COMPLETION [ NOT ] PRESERVE ]
[ ENABLE | DISABLE ]
[ COMMENT '註釋' ]
DO SQL語句;
 
schedule : AT TIMESTAMP [+ INTERVAL interval ] | EVERY interval [ STARTS TIMESTAMP ] [ ENDS TIMESTAMP ]
interval : quantity { YEAR | QUARTER | MONTH | DAY |
           HOUR | MINUTE | WEEK | SECOND |
           YEAR_MONTH | DAY_HOUR | DAY_MINUTE | DAY_SECOND |
           HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND }

關閉事件

ALTER EVENT event_name DISABLE;

開啓事件

ALTER EVENT event_name ENABLE;

刪除事件

DROP EVENT [IF EXISTS ] event_name;

查看所有事件

SHOW EVENTS;

查看定期任務

SELECT event_name,event_definition,interval_value,interval_field,status 
FROM information_schema.EVENTS;

定時規則

  • 週期執行–關鍵字 EVERY
  • 在具體某個時間執行–關鍵字 AT
  • 在某個時間段執行–關鍵字 STARTS ENDS

示例

事件類型有兩種,一種是間隔觸發,一種是特定時間觸發

DROP EVENT IF EXISTS event_test;
CREATE EVENT event_test
ON SCHEDULE EVERY 1 SECOND STARTS '2017-08-22 11:57:00' ENDS '2017-08-22 12:00:00'
ON COMPLETION PRESERVE
ENABLE
COMMENT '每隔一秒向test表插入記錄'
DO INSERT INTO test VALUES(NULL, now());
DROP EVENT IF EXISTS event_test2;
CREATE EVENT event_test2
ON SCHEDULE AT '2017-08-22 12:01:00'
ON COMPLETION PRESERVE
ENABLE
COMMENT '指定時間向test表插入記錄'
DO INSERT INTO test VALUES(999999, now());
on schedule every 1 week //每週執行1次

on schedule at current_timestamp()+interval 5 day //5天后執行
on schedule at '2019-01-01 00:00:00' //在2019年1月1日,0點整執行

on schedule every 1 day starts current_timestamp()+interval 5 day ends current_timestamp()+interval 1 month //5天后開始每天都執行執行到下個月底
on schedule every 1 day ends current_timestamp()+interval 5 day //從現在起每天執行,執行5天
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章