1. 程式人生 > >Mysql中的自定義函式和自定義過程

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

iostableview的建立定義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

AndroidClipDrawable的使用定義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 第二種方法的優點是,你可