存储过程

Stored Routines 的应用

在资料库管理系统的应用中,都必须使用SQL叙述来请资料库执行各种不同的工作。

SQL叙述的特点时 一次只能执行一件工作,所以要完成上列的工作,就必须执行数个SQL叙述,如果这样的一组工作时很常执行的,你就可以考虑把这些要执行的叙述建立为 存储过程 「Stored procedure」

把这一组工作建立为Stored procedure元件以后,以后要执行这些工作时,就可以「呼叫、call」这个建立好的Stored procedure元件:

要建立人口数比「USA」多的国家表格时,只要传入指定的国家代码就可以了:

Stored routines另外提供一种「Stored functions」元件,除了MySQL资料库提供许多各种不同的函式外,你也可以建立自己的函式,这种函式称为Stored functions

你可以自己建立一个名称为「ROUND2」的Stored functions,这个函式固定将一个指定的数值四舍五入到小数两位:

建立好需要的Stored function元件以后,它使用起来就跟你在使用MySQL提供的函式一样

你同样可以在资料库中建立许多需要的Stored functions,把一些比较复杂工作建立为Stored functions元件以后,你就可以跟使用MySQL提供的函式一样来使用它们,同样可以简化许多繁复的工作

存储过程介绍

tored procedures 存储过程 元件也是一种可以建立、维护与删除的资料库元件

  • 表格元件是用来储存资料用的
  • 索引元件是储存索引与增加效率用的;
  • Stored procedures元件是用来「储存程序」用的,程序表示一组特定的工作,如果在使用资料的过程中,常常需要执行一组同样的工作,你就可以考虑把执行工作需要的叙述建立为Stored procedures元件。

不论是 存储过程 stored Procedure 还是 stored Function 如果执行一条叙述就不需要使用 BEGIN ADN 了,当包含多个叙述时,就一定要使用 BEGIN END

DELIMITER $$
CREATE PROCEDURE procedure_name()
  SELECT * FROM vote_record;
DELIMITER ;

--- 多条叙述要使用 BEGIN END

DELIMITER $$
CREATE PROCEDURE procedure_name()
  BEGIN
    SELECT * FROM vote_record;
    SELECT CIOUNT(*) FROM vote_record;
  END $$
DELIMITER ;

基本语法

建立存储过程的语法

DELIMITER $$
CREATE PROCEDURE procedure_name()
  BEGIN
    SELECT * FROM vote_record;
    SELECT CIOUNT(*) FROM vote_record;
  END $$
DELIMITER ;

删除存储过程的语法

'呼叫' 执行 存储过程的语法

Stored Functions 存储函数 介绍

如果MySQL提供的函式无法完成你的工作,或是想要改善一些比较复杂的叙述,你都可以建立需要的Sotred functions元件

跟Stored procedures一样,它也是一种用来「储存程序」的元件,不过建立好的Stored procedures 存储过程元件要使用「CALL」来呼叫,也就是请资料库执行储存在Stored procedures中的工作;

要使用建立好的 Stored functions 元件,就跟使用MySQL提供的函式一样来使用它们。

建立 Stored Functions 元件的基本语法

image

删除Stored functions元件的基本语法:

image

SQL Script、DELIMITER与Stored routines

建立需要的Stored routines元件要使用「CREATE PROCEDURE」或「CREATE FUNCTION」叙述,虽然它们跟其它的SQL叙述一样,也是请资料库执行一件工作,不过Stored routines通常会包含许多需要的叙述,所以通常会使用 SQL script 来执行建立Stored routines的工作

SQL script是一个包含许多SQL叙述的档案,你可以把想要执行的SQL叙述都集中在一个档案中。以建立课程范例资料库的「cmdev.sql」档案来说,它的内容会像这样

image

Mysql 中 -- 开始的话,表示是 注释

MySQL使用分号作为预设的delimiter(分隔符)

MySQL提供「DELIMITER」指令,可以修改预设的delimiter符号

image

-- 使用 DELIMITER 将分隔符设置为 $$
DELIMITER $$

CALL helo(1,2)$$

CALL helo(3,4)$$
-- 通常在结尾将 delimiter 设置为默认的 `;`
DELIMITER ;

在一般的应用时,你通常不会去修改预设的delimiter符号;

可是在建立Stored routines元件的SQL script档案中就一定要使用了

为什么要使用 DELIMITER

这种情况下通常是在命令行的情况下有影响,对ide没有什么影响,因为命令行中执行命令是一行一行的书写,所以如果你输入 select * from ***;之后由于你没有指定分隔符,默认是 ;,所以到这一句就直接执行了,而我们是想要输入更多的语句,就需要指定自定义分隔符了

下列是建立Stored procedure元件的基本内容:

image

完成建立procedure的叙述后,要执行这个叙述来建立需要的procedure元件:

如果一个procedure 元件执行的工作只是这样的话,应该就不需要建立procedure元件了

procedure元件通常会包含许多要执行的叙述,这时候就一定要使用「BEGIN」与「END」

DELIMITER $$
CREATE PROCEDURE peocedure_name()
  BEGIN
    -- 多个叙述
  END $$
DELIMITER ;

以下列的「my_world_count」procedure元件来说,它可以一次查询国家、语言与城市三个表格的数量:

使用SQL script建立functions同样要使用「DELIMITER」关键字设定delimiter。

「CREATE FUNCTION」的语法另外包含 RETURNSRETURN 两个关键字。

下列是建立Stored functions的基本内容:

image

DELIMITER $$
CREATE FUNCTION function_name()
  RETURNS VARCHAR(64)
  RETURN "";
$$
DELIMITER ;

以下列的「my_date」Stored function来说,它会传回「年/月/日时:分:秒星期」格式的日期时间资料:

image

Stored Routines的参数

Stored routines可以使用参数(parameters)让使用者传送资料给stored routines使用,procedures与functions都可以依照需要决定参数的个数与型态。

Stored Functions的参数

Functions参数的决定会比procedures简单,因为functions的参数只是用来接收资料后,在functions中使用。你必须决定每一个参数的名称和型态,再依照想要的顺序定义在functions中:

DELIMITER $$
CREATE FUNCTION function_name()
  RETURNS VARCHAR(64) -- 指定参数类型
  RETURN 'benny';
$$
DELIMITER ;

以下列一个合计功能的function来说,它需要两个「INT」型态的整数参数:

image

在呼叫「my_summary」的时候,依照参数的定义,指定两个要合计的整数数值,这个function会将两个传入的整数数值加起来后回传给你:

image

在呼叫function的时候,一定要依照参数的定义,传送正确个数的参数资料:

除了参数的个数外,你也要遵守参数型态的规定:

一个function的定义不一定需要参数,以下列的范例来说,呼叫「my_date」时并不需要传送任何参数资料,不过无论是否需要参数,在呼叫function时,名称后面的左右刮号是不可以省略的:

Stored Procedures的参数

Procedures参数的定义与functions大致上相同,除了必须决定每一个参数的名称型态与顺序,你还需要决定每一个参数的用途

下列是参数用途的说明:

参数用途 说明
IN 「输入、input」用的参数。这种参数与functions中的参数完全一样,在呼叫procedures时传送资料给procedures用的
OUT 「输出、output」用的参数。在呼叫procedures时,不能接收传送的资料,不过在执行procedures时,可以设定这类参数的值,新的值在执行完成后,可以回传给呼叫的地方使用
INOUT 「输入与输出、input与output」用的参数。同时具有「IN」与「OUT」两种用途

呼叫procedures时要依照定义的参数个数与型态来传送资料:

在呼叫Procedures时传送的参数资料,会因为不同的用途而有不同的限制:

如果违反参数用途上的规定就会发生错误:

所以在呼叫procedures时,「OUT」与「INOUT」参数必须指定变量名称,这是因为「OUT」与「INOUT」参数在执行完成后会回传资料,使用变量名称才可以接收procedures回传的资料:

··· DELIMITER $$ CREATE PROCEDURE test(IN param1 INT, IN param2 INT, IN param3 INT) BEGIN SELECT param1, param2, param3; END $$ DELIMITER ;

CALL test(1,2,3)

···

执行procedures以后,指定给「OUT」与「INOUT」的变数名称,就会储存procedures中设定的值:

如果在呼叫procedures之前,先把参数资料设定为使用者变量,再把它们指定给参数使用:

执行上列呼叫procedures的叙述后,你可以发现设定为「OUT」用途的参数是不能接收参数资料的;而下列查询使用者变数的叙述,可以发现设定为「IN」用途的参数没有回传资料的功能:

以下列的范例来说,呼叫「country_count」需要一个洲名的参数,执行以后,它会使用你的洲名执行查询国家的数量。这个洲名参数的需求,只是用来设定查询条件用的,并不需要回传资料,所以这样的参数适合设定为「IN」:

下列的范例先设定好一个使用者变数储存洲名,再呼叫「country_count」:

在procedures与functions中,MySQL提供一种特别的查询叙述。一般的查询叙述是用来回传需要的资料用的,而这种查询叙述可以把「SELECT」子句中指定的资料指定给变数:

SELECT COUJNT(*) INTO 变量名字

以下列的范例来说,呼叫「country_count2」需要一个洲名的参数,它会使用你的洲名执行查询国家的数量,不过执行以后,它会回传国家的数量给你。所以这个procedure需要第二个参数用来回传国家的数量,以这样的参数需求,国家的数量的参数适合设定为「OUT」:

呼叫「country_count2」时要提供洲名与接收国家数量的变数名称,在procedure执行以后,使用者变数「my_count」就会储存国家数量了:

results matching ""

    No results matching ""