MySQL 變數和條件

来源:http://www.cnblogs.com/chenmh/archive/2016/02/20/5203429.html
-Advertisement-
Play Games

概述 變數在存儲過程中會經常被使用,變數的使用方法是一個重要的知識點,特別是在定義條件這塊比較重要。 mysql版本:5.6 變數定義和賦值 #創建資料庫 DROP DATABASE IF EXISTS Dpro; CREATE DATABASE Dpro CHARACTER SET utf8 ;


概述  

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

 mysql版本:5.6

變數定義和賦值  

#創建資料庫
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]

例如:

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變數賦值 

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

1.變數賦值

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

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明鏈接。

《歡迎交流討論》


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 編寫i2c設備驅動(從設備)一般有兩種方式: 1.用戶自己編寫獨立的從設備驅動,應用程式直接使用即可。 2.linux內核內部已經實現了一個通用的設備驅動,利用通用設備驅動編寫一個應用程式(用戶態驅動),在應用程式中用到大量設備驅動提供的介面,通過應用程式來控制從設備。 匯流排驅動 4.1 概述 I2
  • 一 打開 Apache 的配置文件 httpd.conf 。二 將#LoadModule rewrite_module modules/mod_rewrite前面的#去掉三 在 httpd.conf中添加:<IfModule mod_rewrite.c>RewriteEngine On#Rewrit
  • 每一個應用程式中都有一個NSNotificationCenter實例,用來協助不同的對象之間的通信,任何一個對象都可以向通知中心發佈通知(NSNotication),在通知中描述自己做什麼。其他的感興趣的對象可以申請在某個特定的通知或者特定對象發出通知時接收到這個通知。 一個通知一般包含有3個屬性:
  • 背景:假說有兩個Activity, Activity1和Activity2, 1跳轉到2,如果要在2退出程式,一般網上比較常見的說法是用 System.exit(0) 或是 android.os.Process.killProcess(android.os.Process.myPid()) 但實際應
  • MySQL 提供了資料庫的同步功能,這對我們實現資料庫的冗災、備份、恢復、負載均衡等都是有極大幫助的。本文描述了常見的同步設置方法。 一、準備伺服器 由於MySQL不同版本之間的(二進位日誌)binlog格式可能會不一樣,因此最好的搭配組合是Master的MySQL版本和Slave的版本相同或者更低
  • 最近要優化Oracle資料庫的效率,然後在網上查了很多判斷記錄是否存在的高效率方法網上有很多的建議第一種方法,我做了一個測試,但是可能數據量不夠大,42667條記錄,不知道很大的數據量是什麼一個情況網上好多高效的建議方式 select * from item where item='1B241371
  • 隨著生產數據的日誌越來越大,硬碟空間越來越小的時候,我們就需要考慮清理一下資料庫日誌,以前都是手工弄,現在找到一個語句直接自動處理,方便很多,分享一下。 DUMP TRANSACTION CMSDemo WITH NO_LOG BACKUP LOG CMSDemo WITH NO_LOG DBCC
  • SQL Server代理是所有實時資料庫的核心。代理有很多不明顯的用法,因此系統的知識,對於開發人員還是DBA都是有用的。這系列文章會通俗介紹它的很多用法。 在這個系列的前一篇文章里,你學習瞭如何在SQL Server代理作業步驟里啟動外部程式。你可以使用過時的ActiveX系統,從虛擬命令提示符里
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...