MySQL 變量和條件

概述  

 變量在存儲過程當中會常常被使用,變量的使用方法是一個重要的知識點,特別是在定義條件這塊比較重要。mysql

 mysql版本:5.6sql

變量定義和賦值  

#建立數據庫
DROP DATABASE IF EXISTS Dpro;
CREATE  DATABASE Dpro
CHARACTER SET utf8
;

USE Dpro;

#建立部門表
DROP TABLE IF EXISTS Employee;
CREATE TABLE Employee
(id INT NOT NULL PRIMARY KEY COMMENT '主鍵',
 name VARCHAR(20) NOT NULL COMMENT '人名',
 depid INT NOT NULL COMMENT '部門id'
);

INSERT INTO Employee(id,name,depid) VALUES(1,'',100),(2,'',101),(3,'',101),(4,'',102),(5,'',103);

declare定義變量數據庫

在存儲過程和函數中經過declare定義變量在BEGIN...END中,且在語句以前。而且能夠經過重複定義多個變量函數

注意:declare定義的變量名不能帶‘@’符號,mysql在這點作的確實不夠直觀,每每變量名會被錯成參數或者字段名。測試

DECLARE var_name[,...] type [DEFAULT value]

例如:spa

DROP PROCEDURE IF EXISTS Pro_Employee;
DELIMITER $$
CREATE PROCEDURE Pro_Employee(IN pdepid VARCHAR(20),OUT pcount INT )
READS SQL DATA
SQL SECURITY INVOKER
BEGIN
DECLARE pname VARCHAR(20) DEFAULT '陳';
SELECT COUNT(id) INTO pcount FROM Employee WHERE depid=pdepid;

END$$
DELIMITER ;

SET變量賦值 3d

SET除了能夠給已經定義好的變量賦值外,還能夠指定賦值並定義新變量,且SET定義的變量名能夠帶‘@’符號,SET語句的位置也是在BEGIN ....END之間的語句以前。code

1.變量賦值blog

SET var_name = expr [, var_name = expr] ...
DROP PROCEDURE IF EXISTS Pro_Employee;
DELIMITER $$
CREATE PROCEDURE Pro_Employee(IN pdepid VARCHAR(20),OUT pcount INT )
READS SQL DATA
SQL SECURITY INVOKER
BEGIN
DECLARE pname VARCHAR(20) DEFAULT '陳';
SET pname='王';
SELECT COUNT(id) INTO pcount FROM Employee WHERE depid=pdepid AND name=pname;

END$$
DELIMITER ;

CALL Pro_Employee(101,@pcount);

  SELECT @pcount;事務

 2.經過賦值定義變量

DROP PROCEDURE IF EXISTS Pro_Employee;
DELIMITER $$
CREATE PROCEDURE Pro_Employee(IN pdepid VARCHAR(20),OUT pcount INT )
READS SQL DATA
SQL SECURITY INVOKER
BEGIN
DECLARE pname VARCHAR(20) DEFAULT '';
SET pname='';
SET @ID=1;
SELECT COUNT(id) INTO pcount FROM Employee WHERE depid=pdepid AND name=pname;
SELECT @ID;

END$$
DELIMITER ;

CALL Pro_Employee(101,@pcount);

SELECT ... INTO語句賦值

 經過select into語句能夠將值賦予變量,也能夠之間將該值賦值存儲過程的out參數,上面的存儲過程select into就是之間將值賦予out參數。

DROP PROCEDURE IF EXISTS Pro_Employee;
DELIMITER $$
CREATE PROCEDURE Pro_Employee(IN pdepid VARCHAR(20),OUT pcount INT )
READS SQL DATA
SQL SECURITY INVOKER
BEGIN
DECLARE pname VARCHAR(20) DEFAULT '';
DECLARE Pid INT; SELECT COUNT(id) INTO Pid FROM Employee WHERE depid=pdepid AND name=pname; SELECT Pid;

END$$
DELIMITER ;

CALL Pro_Employee(101,@pcount);

這個存儲過程就是select into將值賦予變量;

 

表中並無depid=101 and name='陳'的記錄。 

條件  

條件的做用通常用在對指定條件的處理,好比咱們遇到主鍵重複報錯後該怎樣處理。 

定義條件

 定義條件就是事先定義某種錯誤狀態或者sql狀態的名稱,而後就能夠引用該條件名稱開作條件處理,定義條件通常用的比較少,通常會直接放在條件處理裏面。

DECLARE condition_name CONDITION FOR condition_value
 
condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | mysql_error_code

1.沒有定義條件:

DROP PROCEDURE IF EXISTS Pro_Employee_insert;
DELIMITER $$
CREATE PROCEDURE Pro_Employee_insert()
MODIFIES SQL DATA
SQL SECURITY INVOKER
BEGIN
SET @ID=1;
INSERT INTO Employee(id,name,depid) VALUES(1,'',100);
SET @ID=2;
INSERT INTO Employee(id,name,depid) VALUES(6,'',100);
SET @ID=3;

END$$
DELIMITER ;

#執行存儲過程
CALL Pro_Employee_insert();

#查詢變量值
SELECT @ID,@X;

 報主鍵重複的錯誤,其中1062是主鍵重複的錯誤代碼,23000是sql錯誤狀態

2.定義處理條件

DROP PROCEDURE IF EXISTS Pro_Employee_insert;
DELIMITER $$
CREATE PROCEDURE Pro_Employee_insert()
MODIFIES SQL DATA
SQL SECURITY INVOKER
BEGIN
#定義條件名稱,
DECLARE reprimary CONDITION FOR 1062;
#引用前面定義的條件名稱並作賦值處理
DECLARE EXIT HANDLER FOR reprimary SET @x=1;
SET @ID=1;
INSERT INTO Employee(id,name,depid) VALUES(1,'',100);
SET @ID=2;
INSERT INTO Employee(id,name,depid) VALUES(6,'',100);
SET @ID=3;

END$$
DELIMITER ;

CALL Pro_Employee_insert();

SELECT @ID,@X;

在執行存儲過程的步驟中並無報錯,可是因爲我定義的是exit,因此在遇到報錯sql就終止往下執行了。

接下來看看continue的不一樣

DROP PROCEDURE IF EXISTS Pro_Employee_insert;
DELIMITER $$
CREATE PROCEDURE Pro_Employee_insert()
MODIFIES SQL DATA
SQL SECURITY INVOKER
BEGIN
#定義條件名稱,
DECLARE reprimary CONDITION FOR SQLSTATE '23000';
#引用前面定義的條件名稱並作賦值處理
DECLARE CONTINUE HANDLER FOR reprimary SET @x=1;
SET @ID=1;
INSERT INTO Employee(id,name,depid) VALUES(1,'',100);
SET @ID=2;
INSERT INTO Employee(id,name,depid) VALUES(6,'',100);
SET @ID=3;

END$$
DELIMITER ;

CALL Pro_Employee_insert();

SELECT @ID,@X;

其中紅色標示的是和上面不一樣的地方,這裏定義條件使用的是SQL狀態,也是主鍵重複的狀態;而且這裏使用的是CONTINUE就是遇到錯誤繼續往下執行。

條件處理

條件處理就是之間定義語句的錯誤的處理,省去了前面定義條件名稱的步驟。

DECLARE handler_type HANDLER FOR condition_value[,...] sp_statement
 
handler_type:
    CONTINUE| EXIT| UNDO
 
condition_value:
    SQLSTATE [VALUE] sqlstate_value
  | condition_name
  | SQLWARNING
  | NOT FOUND
  | SQLEXCEPTION
  | mysql_error_code

handler_type:遇到錯誤是繼續往下執行仍是終止,目前UNDO還沒用到。

CONTINUE:繼續往下執行

EXIT:終止執行

condition_values:錯誤狀態

SQLSTATE [VALUE] sqlstate_value:就是前面講到的SQL錯誤狀態,例如主鍵重複狀態SQLSTATE '23000'

condition_name:上面講到的定義條件名稱;

SQLWARNING:是對全部以01開頭的SQLSTATE代碼的速記,例如:DECLARE CONTINUE HANDLER FOR SQLWARNING。

NOT FOUND:是對全部以02開頭的SQLSTATE代碼的速記。

SQLEXCEPTION:是對全部沒有被SQLWARNING或NOT FOUND捕獲的SQLSTATE代碼的速記。

mysql_error_code:是錯誤代碼,例如主鍵重複的錯誤代碼是1062,DECLARE CONTINUE HANDLER FOR 1062

 

語句:

DROP PROCEDURE IF EXISTS Pro_Employee_insert;
DELIMITER $$
CREATE PROCEDURE Pro_Employee_insert()
MODIFIES SQL DATA
SQL SECURITY INVOKER
BEGIN
#引用前面定義的條件名稱並作賦值處理 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SET @x=2;
#開始事務必須在DECLARE以後
START TRANSACTION ; SET @ID=1; INSERT INTO Employee(id,name,depid) VALUES(7,'陳',100); SET @ID=2; INSERT INTO Employee(id,name,depid) VALUES(6,'陳',100); SET @ID=3; IF @x=2 THEN ROLLBACK; ELSE COMMIT; END IF; END
$$ DELIMITER ;
#執行存儲過程
CALL Pro_Employee_insert();
#查詢
SELECT @ID,@X;

經過SELECT @ID,@X能夠知道存儲過程已經執行到了最後,可是由於存儲過程後面有作回滾操做整個語句進行了回滾,因此ID=7的符合條件的記錄也被回滾了。

總結  

變量的使用不單單隻有這些,在光標中條件也是一個很好的功能,剛纔測試的是continue若是使用EXIT的話語句執行完「SET @ID=2;」就不往下執行了,後面的IF也不被執行整個語句不會被回滾,可是使用CONTINE當出現錯誤後仍是會往下執行若是後面的語句還有不少的話整個回滾的過程將會很長,在這裏能夠利用循環,當出現錯誤馬上退出循環執行後面的if回滾操做,在下一篇講循環語句會寫到,歡迎關注。

 

 

備註:

    做者:pursuer.chen

    博客:http://www.cnblogs.com/chenmh

本站點全部隨筆都是原創,歡迎你們轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明連接。

《歡迎交流討論》

相關文章
相關標籤/搜索