Mysql中的自定義函式和自定義過程
MYSQL中建立儲存過程和函式分別使用CREATE PROCEDURE和CREATE FUNCTION
使用CALL語句來呼叫儲存過程,儲存過程也可以呼叫其他儲存過程
函式可以從語句外呼叫,能返回標量值
建立儲存過程
語法
CREATE PROCEDURE sp_name ([ proc_parameter ]) [ characteristics..] routine_body
proc_parameter指定儲存過程的引數列表,列表形式如下:
[IN|OUT|INOUT] param_name type
其中in表示輸入引數,out表示輸出引數,inout表示既可以輸入也可以輸出;param_name表示引數名稱;type表示引數的型別
該型別可以是MYSQL資料庫中的任意型別
有以下取值:
characteristic: LANGUAGE SQL | [NOT] DETERMINISTIC | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA } | SQL SECURITY { DEFINER | INVOKER } | COMMENT 'string' routine_body: Valid SQL procedure statement or statements
LANGUAGE SQL :說明routine_body部分是由SQL語句組成的,當前系統支援的語言為SQL,SQL是LANGUAGE特性的唯一值
[NOT] DETERMINISTIC :指明儲存過程執行的結果是否正確。DETERMINISTIC 表示結果是確定的。每次執行儲存過程時,相同的輸入會得到
相同的輸出。
[NOT] DETERMINISTIC 表示結果是不確定的,相同的輸入可能得到不同的輸出。如果沒有指定任意一個值,預設為[NOT] DETERMINISTIC
CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA:指明子程式使用SQL語句的限制。
CONTAINS SQL表明子程式包含SQL語句,但是不包含讀寫資料的語句;
NO SQL表明子程式不包含SQL語句;
READS SQL DATA:說明子程式包含讀資料的語句;
MODIFIES SQL DATA表明子程式包含寫資料的語句。
預設情況下,系統會指定為CONTAINS SQL
SQL SECURITY { DEFINER | INVOKER } :指明誰有許可權來執行。DEFINER 表示只有定義者才能執行
INVOKER 表示擁有許可權的呼叫者可以執行。預設情況下,系統指定為DEFINER
COMMENT 'string' :註釋資訊,可以用來描述儲存過程或函式
routine_body是SQL程式碼的內容,可以用BEGIN...END來表示SQL程式碼的開始和結束。
下面的語句建立一個查詢t1表全部資料的儲存過程
DROP PROCEDURE IF EXISTS Proc; DELIMITER // CREATE PROCEDURE Proc() BEGIN SELECT * FROM t3; END// DELIMITER ; CALL Proc();
t3表是我們上一節建立的表
這裡的邏輯是
1、先判斷是否有Proc() 這個儲存過程,有就drop掉
2、建立Proc() 儲存過程
3、執行Proc() 儲存過程
注意:“DELIMITER //”語句的作用是將MYSQL的結束符設定為//,因為MYSQL預設的語句結束符為分號;,為了避免與儲存過程
中SQL語句結束符相沖突,需要使用DELIMITER 改變儲存過程的結束符,並以“END//”結束儲存過程。
儲存過程定義完畢之後再使用DELIMITER ;恢復預設結束符。DELIMITER 也可以指定其他符號為結束符!!!!!!!!!!!
如果你是這樣寫的話,就會得到如下錯誤,初學者很容易犯這個錯誤,包括本人
CREATE PROCEDURE Proc() BEGIN SELECT * FROM t3; END Query: CREATE PROCEDURE Proc() BEGIN SELECT * FROM t3 Error Code: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3 Execution Time : 0 sec Transfer Time : 0 sec Total Time : 0.001 sec --------------------------------------------------- Query: END Error Code: 1064
建立名為CountProc的儲存過程,程式碼如下:
DELIMITER // CREATE PROCEDURE CountProc(OUT param1 INT) BEGIN SELECT COUNT(*) INTO param1 FROM t3; END// DELIMITER ;
上面程式碼的作用是建立一個獲取t3表記錄數的儲存過程,名稱是CountProc,
COUNT(*)計算後把結果放入引數param1中。
注意:當使用DELIMITER命令時,應該避免使用反斜槓(\)字元,因為反斜槓是MYSQL的轉義字元!!!
儲存函式
建立儲存函式,需要使用CREATE FUNCTION語句,基本語法如下:
CREATE FUNCTION func_name([func_parameter]) RETURNS TYPE [characteristics...] routine_body
CREATE FUNCTION為用來建立儲存函式的關鍵字;func_name表示儲存函式的名稱
func_parameter為儲存函式的引數列表,引數列表如下
[IN|OUT|INOUT]PARAM_NAMETYPE
其中,IN表示輸入引數,OUT表示輸出引數,INOUT表示既可以輸入也可以輸出;
param_name表示引數名稱;type表示引數型別,該型別可以是MYSQL資料庫中的任意型別
RETURNS TYPE語句表示函式返回資料的型別;characteristics:指定儲存函式的特性,取值與建立儲存過程時相同
建立儲存函式,名稱為NameByT,該函式返回SELECT語句的查詢結果,數值型別為字串型
DELIMITER // CREATE FUNCTION NameByT() RETURNS CHAR(50) RETURN (SELECT NAME FROM t3 WHERE id=2); // DELIMITER ;
注意:RETURNS CHAR(50)資料型別的時候,RETURNS 是有S的,而RETURN (SELECT NAME FROM t3 WHERE id=2)的時候RETURN是沒有S的
所以有時候大家可能覺得MYSQL很煩,誰不知是自己寫錯了
這裡有一個方法,就是利用SQLYOG的程式碼格式化功能,選中要格式化的程式碼,然後按F12,如果能格式化,證明你的程式碼沒有問題,如果不能格式化
證明你寫的程式碼有問題!!!
不加s的話就會出現語法錯誤了
Query: create function NameByT() return char(50) return (select name from t3 where id=2) Error Code: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'return char(50) return (select name from t3 where id=2)' at line 2 Execution Time : 0 sec Transfer Time : 0 sec Total Time : 0.003 sec -----------------------------
呼叫函式
SELECT nameByT()
如果在儲存函式中的RETURN語句返回一個型別不同於函式的RETURNS子句中指定型別的值,返回值將被強制轉換為恰當的型別。
例如,如果一個函式返回一個SET或ENUM值,但是RETURN語句返回一個整數,對於SET成員集的相應ENUM成員,從函式返回的值
是字串。
指定引數為IN、OUT、INOUT只對PROCEDURE是合法的。
(FUNCTION中總是預設是IN引數)RETURNS子句對FUNCTION做指定,對函式而言這是強制的。
他用來指定函式的返回型別,而且函式體必須包含一個RETURN value語句
變數的使用
變數可以在子程式中宣告並使用,這些變數的作用範圍是在BEGIN...END程式中
1、定義變數
在儲存過程中定義變數
DECLARE var_name[,varname]...date_type[DEFAULT VALUE];
var_name為區域性變數的名稱。DEFAULT VALUE子句給變數提供一個預設值。值除了可以被宣告為一個常數外,還可以被指定為一個表示式。
如果沒有DEFAULT子句,初始值為NULL
DECLARE MYPARAM INT DEFAULT 100;
2、為變數賦值
定義變數之後,為變數賦值可以改變變數的預設值,MYSQL中使用SET語句為變數賦值
SET var_name=expr[,var_name=expr]...
在儲存過程中的SET語句是一般SET語句的擴充套件版本。
被SET的變數可能是子程式內的變數,或者是全域性伺服器變數,如系統變數或者使用者變數
他執行SET a=x,b=y,....
宣告3個變數,分別為var1,var2和var3
DECLARE var1,var2,var3 INT; SET var1=10,var2=20; SET var3=var1+var2;
MYSQL中還可以通過SELECT...INTO為一個或多個變數賦值
DECLARE NAME CHAR(50); DECLARE id DECIMAL(8,2); SELECT id,NAME INTO id ,NAME FROM t3 WHERE id=2;
定義條件和處理程式
特定條件需要特定處理。這些條件可以聯絡到錯誤,以及子程式中的一般流程控制。定義條件是事先定義程式執行過程中遇到的問題,
處理程式定義了在遇到這些問題時候應當採取的處理方式,並且保證儲存過程或函式在遇到警告或錯誤時能繼續執行。
這樣可以增強儲存程式處理問題的能力,避免程式異常停止執行
1、定義條件
DECLARE condition_name CONDITION FOR[condition_type] [condition_type]: SQLSTATE[VALUE] sqlstate_value |mysql_error_code
condition_name:表示條件名稱
condition_type:表示條件的型別
sqlstate_value和mysql_error_code都可以表示mysql錯誤
sqlstate_value為長度5的字串錯誤程式碼
mysql_error_code為數值型別錯誤程式碼,例如:ERROR1142(42000)中,sqlstate_value的值是42000,
mysql_error_code的值是1142
這個語句指定需要特殊處理條件。他將一個名字和指定的錯誤條件關聯起來。
這個名字隨後被用在定義處理程式的DECLARE HANDLER語句中
定義ERROR1148(42000)錯誤,名稱為command_not_allowed。
可以用兩種方法定義
//方法一:使用sqlstate_value DECLARE command_not_allowed CONDITION FOR SQLSTATE '42000' //方法二:使用mysql_error_code DECLARE command_not_allowed CONDITION FOR SQLSTATE 1148
2.定義處理程式
MySQL中可以使用DECLARE關鍵字來定義處理程式。其基本語法如下:
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引數指明錯誤的處理方式,該引數有3個取值。這3個取值分別是CONTINUE、EXIT和UNDO。
CONTINUE表示遇到錯誤不進行處理,繼續向下執行;
EXIT表示遇到錯誤後馬上退出;
UNDO表示遇到錯誤後撤回之前的操作,MySQL中暫時還不支援這種處理方式。
注意:通常情況下,執行過程中遇到錯誤應該立刻停止執行下面的語句,並且撤回前面的操作。
但是,MySQL中現在還不能支援UNDO操作。
因此,遇到錯誤時最好執行EXIT操作。如果事先能夠預測錯誤型別,並且進行相應的處理,那麼可以執行CONTINUE操作。
condition_value引數指明錯誤型別,該引數有6個取值。
sqlstate_value和mysql_error_code與條件定義中的是同一個意思。
condition_name是DECLARE定義的條件名稱。
SQLWARNING表示所有以01開頭的sqlstate_value值。
NOT FOUND表示所有以02開頭的sqlstate_value值。
SQLEXCEPTION表示所有沒有被SQLWARNING或NOT FOUND捕獲的sqlstate_value值。
sp_statement表示一些儲存過程或函式的執行語句。
下面是定義處理程式的幾種方式。程式碼如下:
//方法一:捕獲sqlstate_value DECLARE CONTINUE HANDLER FOR SQLSTATE '42000' SET @info='CAN NOT FIND'; //方法二:捕獲mysql_error_code DECLARE CONTINUE HANDLER FOR 1148SET @info='CAN NOT FIND'; //方法三:先定義條件,然後呼叫 DECLARE can_not_find CONDITION FOR 1146 ; DECLARE CONTINUE HANDLER FOR can_not_find SET @info='CAN NOT FIND'; //方法四:使用SQLWARNING DECLARE EXIT HANDLER FOR SQLWARNING SET @info='ERROR'; //方法五:使用NOT FOUND DECLARE EXIT HANDLER FOR NOT FOUND SET @info='CAN NOT FIND'; //方法六:使用SQLEXCEPTION DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @info='ERROR';
上述程式碼是6種定義處理程式的方法。
第一種方法是捕獲sqlstate_value值。如果遇到sqlstate_value值為42000,執行CONTINUE操作,並且輸出"CAN NOT FIND"資訊。
第二種方法是捕獲mysql_error_code值。如果遇到mysql_error_code值為1148,執行CONTINUE操作,並且輸出"CAN NOT FIND"資訊。
第三種方法是先定義條件,然後再呼叫條件。這裡先定義can_not_find條件,遇到1148錯誤就執行CONTINUE操作。
第四種方法是使用SQLWARNING。SQLWARNING捕獲所有以01開頭的sqlstate_value值,然後執行EXIT操作,並且輸出"ERROR"資訊。
第五種方法是使用NOT FOUND。NOT FOUND捕獲所有以02開頭的sqlstate_value值,然後執行EXIT操作,並且輸出"CAN NOT FIND"資訊。
第六種方法是使用SQLEXCEPTION。SQLEXCEPTION捕獲所有沒有被SQLWARNING或NOT FOUND捕獲的sqlstate_value值,然後執行EXIT操作,並且輸出"ERROR"資訊
定義條件和處理程式
相關推薦
Mysql中的自定義函式和自定義過程
MYSQL中建立儲存過程和函式分別使用CREATE PROCEDURE和CREATE FUNCTION使用CALL語句來呼叫儲存過程,儲存過程也可以呼叫其他儲存過程函式可以從語句外呼叫,能返回標量值建立儲存過程語法CREATE PROCEDURE sp_name ([ pro
laravel自定義函式和自定義類
1. 建立檔案 app/helpers.php<?php // 示例函式 function foo() { return "foo"; }2. 修改專案 composer.json在專案 composer.json 中 autoload 部分裡的 files 欄位加
mysql中的單行函式和多行函式(講義)
--查詢工作為SALESMAN,MANAGER並且工資大於2500的員工資訊 --and關鍵字的執行級別高於or --可以使用小括號提升條件的執行級別,使用了小括號的級別是最高的 select * from emp where (job='SALESMAN' or j
學會使用MySQL中自定義函式和儲存過程
一、快速瞭解什麼是儲存過程和函式? 儲存過程和函式是事先經過編譯並存儲在資料庫中的一段 SQL 語句的集合,呼叫儲存過程 和函式可以簡化應用開發人員的很多工作,減少資料在資料庫和應用伺服器之間的傳輸,對 於提高資料處理的效率是有好處的。 在對儲存過程或函式進行操作時,需要
MySQL自定義函式和儲存過程的區別:
自定義函式和儲存過程的區別: 1)一般來說,儲存過程實現的功能要複雜一點,而函式的實現的功能針對性比較強。儲存過程,功能強大,可以執行包括修改表等一系列資料庫操作;使用者定義函式不能用於執行一組修改全域性資料庫狀態的操作。 2)對於儲存過程來說可以返回引數,如記錄集,而函式只能返回值或者表物件。函式只能
初學mysql(十)-資料庫之儲存過程、函式與遊標-自定義函式和流程控制(下)
上一篇部落格講了儲存過程、函式、以及遊標,這一篇部落格接著上一篇部落格來說。首先說說mysql資料庫中的流程控制及自定義函式的使用。 自定義函式: 根據所需要的功能,使用流程控制來完成所需要的功能,完成功能的程式碼就稱為自定義函式。要想完成自定義函式就必須學會流程控制的使
MySQL利用自定義函式和儲存過程建立海量表,並使用索引優化
昨天學習韓順平老師的視訊時明白了上一章explain的意義,為了自己的聯絡,我學著建立了一個海量表,供自己練習使用。 程式碼如下: #建立表DEPT CREATE TABLE dept( /*部門表*/ deptno MEDIUMINT UN
mysql中創建用戶自定義函數
mysql 用戶自定義函數總有一些復雜的邏輯我們還需要多處使用,此時就顯現出函數的重要性。 mysql函數的要素 函數名 參數列表 函數體 返回值 定義語法 create function fun_name(參數列表) returns 返回值類型 函數體 示例 不帶參數 delimiter $$ creat
oracle中的預定異常和自定義異常
預定異常 oracle中的預定異常情況大約有24個,對於這種異常情況的處理,無須再程式中定義,可用oracle自動引發,常見的預定異常如下 異常 說明 ACCESS_INTO_NULL 在未初始化物件時出現 CAS
hive中自定義函式及自定義json字串解析函式
hive中如何定義自己的函式 寫一個Java 程式,實現想要的函式功能 1.匯入hive安裝目錄的lib目錄的包 2新建一個類繼承 UDF類 3.過載父類中evaluate方法; 4.寫下自己的邏輯 package test; import
【FastReport教程】如何在報表設計器中使用帶有函式的自定義庫
在報表設計器中的內建函式庫並不是很小,但有時候仍然缺乏一些特定的功能。由於報表中的指令碼,可以輕鬆實現所需的功能。但是,如果許多記錄中需要此功能呢?每次都將它新增到報表指令碼中?當然不是。可以在連線到報表設計器的庫中收集所有需要的函式。需要庫與報表位於同一資料夾中,建立一
django中使用自定義過濾器和自定義標籤
自定義過濾器 首先在app底下新建一個templatetags目錄,裡面新增兩個檔案,目錄結構如下: 然後在settings.py中把templatetags目錄作為app註冊 INSTALLED_APPS = [ 'django.cont
Shell程式設計-自定義函式和shell指令碼除錯
1.自定義函式函式代表著一個或一組命令的集合,表示一個功能模組,常用於模組化程式設計一下是關於函式的重要說明 在shell中,函式必須先定義,再呼叫 使用 return value來獲取函式的返回值 函式在當前shell中執行,可以使用指令碼中的變數函式的格
Java中的equals方法和自定義比較器
class Student { private String name; private int age; Student(String name,int age) { this.name = name; this.age = age; } public S
儲存過程、觸發器和使用者自定義函式實驗 (儲存過程)
儲存過程、觸發器和使用者自定義函式實驗 實驗內容一 練習教材中儲存過程、觸發器和使用者自定義函式的例子。教材中的BookSales資料庫,在群共享中,檔名為BookSales.bak。 實驗內容二 針對附件1中的教學活動資料庫,完成下面的實驗內容。 1、儲存過程 (
檢視內建函式和自定義函式的效率
<html><head><title>study</title><meta http-equiv="content-type" content="text/html;charset=gb2312" /><script type="text/ja
ios中tableview的建立和自定義cell的封裝
#import "HGYwaitServiceViewController.h" #import "HGYWaitingserveCell.h" @interface HGYwaitServic
hive內建函式和自定義函式的使用
1.hive函式的分類 內建函式和自定義函式 1.1、內建函式 1、查詢有哪些內建函式: show functions;2、查詢某個內建函式怎麼使用desc function extended concat;1.2、自定義函式 分三大類:1、UDF : user defin
Android中ClipDrawable的使用和自定義ProgressBar
package com.example.ztest2; import java.lang.ref.WeakReference; import android.content.Context; import android.content.res.TypedArray; import android.gra
C#排序函式和自定義比較器
在C#中,要比較兩個陣列,可以呼叫 System.Array.Sort(...)方法 List等也有Sort()方法 有兩種方式可以為自己的類提供排序; 1.類實現介面 IComparable 2.建立比較器類,該類實現介面IComparer 第二種方法的優點是,你可