10bet网址
MySQL 8.0参考手册
相关的文档10bet官方网站 下载本手册
PDF(美国高级主任)- 41.1 mb
PDF (A4)- 41.2 mb
PDF (RPM)- 39.8 mb
HTML下载(TGZ)- 9.5 mb
HTML下载(Zip)- 9.6 mb
HTML下载(RPM)- 8.1 mb
手册页(TGZ)- 260.5 kb
手册页(Zip)- 371.7 kb
信息(Gzip)- 3.9 mb
信息(邮政编码)- 3.9 mb
本手册节选

MySQL 8.0参考手册/.../ 创建过程语句和创建函数语句

13.1.17 CREATE PROCEDURE和CREATE FUNCTION语句

创建[definer = .用户)程序sp_name([proc_parameter[,...]]) [特征…]routine_body创建[definer = .用户)函数sp_name([func_parameter[…]])返回类型特征…]routine_bodyproc_parameter: [in | out | inout]param_name类型func_parameterparam_name类型类型任何有效的MySQL数据类型特征{注释'字符串' |语言SQL |[不]确定性|{包含SQL | no SQL |读取SQL数据|修改SQL数据}| SQL安全{定义器|调用器}}routine_body有效的SQL例程语句

这些语句用于创建存储例程(存储过程或函数)。也就是说,服务器知道指定的例程。默认情况下,存储的例程与默认数据库相关联。若要显式地将例程与给定数据库关联,请将名称指定为db_name.sp_name当你创建它的时候。

创建函数语句在MySQL中也用于支持udf(用户定义函数)。看到第13.7.4.1节“用户定义函数的CREATE FUNCTION语句”.UDF可以看作是一个外部存储函数。存储函数与udf共享它们的名称空间。看到第9.2.5节,“函数名解析和解析”,用于描述服务器如何解释对不同类型函数的引用的规则。

要调用存储过程,请使用调用声明(见第13.2.1节“CALL语句”).若要调用存储函数,请在表达式中引用它。函数在表达式求值期间返回一个值。

创建过程而且创建函数要求创建程序特权。如果定义者子句存在时,所需的特权取决于用户值,如中所讨论第25.6节“存储对象访问控制”.如果启用了二进制日志记录,创建函数可能需要超级特权,如中所讨论第25.7节“存储程序二进制日志记录”

默认情况下,MySQL自动授予改变日常而且执行例程创建者的特权。属性可以更改此行为automatic_sp_privileges系统变量。看到第25.2.2节,“存储例程和MySQL特权”

定义者而且SQL安全子句指定在例行执行时检查访问特权时使用的安全上下文,如本节后面所述。

如果例程名称与内置SQL函数的名称相同,则会发生语法错误,除非在定义例程或稍后调用例程时在名称和后面的括号之间使用空格。出于这个原因,避免对自己存储的例程使用现有SQL函数的名称。

IGNORE_SPACESQL模式适用于内置函数,而不适用于存储的例程。在存储的例程名称后总是允许有空格,无论是否IGNORE_SPACE启用。

括号内的参数列表必须始终存在。如果没有参数,则为空参数列表()应该使用。参数名不区分大小写。

每个参数都是参数。若要为参数指定其他参数,请使用关键字INOUT在参数名前面。

请注意

将参数指定为,,或INOUT只对a有效过程.对于一个函数,参数总是视为参数。

一个参数将值传递给过程。过程可以修改该值,但是当过程返回时,调用方不可见修改。一个参数将一个值从过程传递回调用方。它的初始值是,并且它的值在过程返回时对调用者可见。一个INOUT参数由调用方初始化,可以由过程修改,并且在过程返回时调用方可以看到过程所做的任何更改。

为每一个INOUT参数中传递用户定义的变量调用语句调用过程,以便在过程返回时获取其值。如果从另一个存储过程或函数中调用过程,还可以将例程参数或局部例程变量作为INOUT参数。如果从触发器内调用过程,也可以传递新的。col_name作为一个INOUT参数。

有关未处理条件对过程参数的影响的信息,请参见第13.6.7.8节“条件处理和OUT或INOUT参数”

例程参数不能在例程内准备的语句中引用;看到第25.8节“存储程序的限制”

下面的示例显示了一个简单的存储过程,给定一个国家代码,该存储过程计算出现在城市表格世界数据库。类型传递国家代码参数返回城市计数参数:

mysql> delimiter // mysql> CREATE PROCEDURE citycount (IN country CHAR(3), OUT cities INT) BEGIN SELECT COUNT(*) INTO cities FROM world。国家代码=国家;END//查询OK, 0 rows affected(0.01秒)mysql> delimiter;mysql> CALL citycount('JPN', @cities);——日本城市查询OK, 1行影响(0.00秒)mysql> SELECT @cities;+---------+ | @ 城市  | +---------+ | 248年  | +---------+ 1行组(0.00秒)mysql >调用citycount(联邦铁路局,@cities);——法国的城市查询OK, 1行影响(0.00秒)mysql> SELECT @城市+---------+ | @ 城市  | +---------+ | 40  | +---------+ 1行集(0.00秒)

该示例使用mysql客户端分隔符命令更改语句分隔符//在定义过程时。这将启用在过程体中使用的分隔符,该分隔符将传递给服务器,而不是由mysql本身。看到第25.1节“定义存储程序”

返回子句只能用于函数,这是强制性的。它表示函数的返回类型,并且函数体必须包含返回价值声明。如果返回语句返回不同类型的值,该值被强制转换为正确的类型。例如,如果函数指定枚举的价值返回条款,但返回语句返回一个整数,函数返回的值是对应的字符串枚举集合的成员成员。

下面的示例函数接受一个参数,使用SQL函数执行操作,并返回结果。在这种情况下,没有必要使用分隔符因为函数定义不包含内部语句分隔符:

mysql>返回CHAR(50) DETERMINISTIC RETURN CONCAT(' hello,',s,'!');mysql> SELECT hello('world');+----------------+ | 你好(“世界上 ') | +----------------+ | 你好,世界!| +----------------+ 1 row in set (0.00 sec)

参数类型和函数返回类型可以声明为使用任何有效的数据类型。的核对属性前加字符集规范。

routine_body由有效的SQL例程语句组成。这可以是一个简单的语句,例如选择插入,或用开始而且结束.复合语句可以包含声明、循环和其他控制结构语句。中描述了这些语句的语法第13.6节“复合语句语法”.实际上,存储函数倾向于使用复合语句,除非函数体由单个语句组成返回声明。

MySQL允许例程包含DDL语句,例如创建而且下降.MySQL还允许存储过程(但不允许存储函数)包含SQL事务语句,例如提交.存储函数不能包含执行显式或隐式提交或回滚的语句。SQL标准并不要求对这些语句的支持,该标准规定每个DBMS供应商可以决定是否允许它们。

返回结果集的语句可以在存储过程中使用,但不能在存储函数中使用。这项禁令包括选择没有变量的语句var_list子句和其他语句,如显示,解释,检查表.对于可以在函数定义时确定返回结果集的语句,使用不允许从函数返回结果集发生错误(ER_SP_NO_RETSET).对于只能在运行时确定返回结果集的语句,可以使用在给定的上下文中,%s不能返回结果集发生错误(ER_SP_BADSELECT).

使用不允许存储例程中的语句。当调用一个例程时,隐式使用db_name执行(并在例程终止时撤消)。使例程在执行时具有给定的默认数据库。对除例程默认数据库之外的数据库中的对象的引用应使用适当的数据库名称进行限定。

有关存储例程中不允许的语句的其他信息,请参见第25.8节“存储程序的限制”

有关从用具有MySQL接口的语言编写的程序中调用存储过程的信息,请参见第13.2.1节“CALL语句”

MySQL存储sql_mode当一个例程被创建或改变时,系统变量设置生效,并且总是在这个设置生效时执行例程,当例程开始执行时,不管当前的服务器SQL模式如何

从调用方的SQL模式切换到例程的SQL模式发生在对参数求值并将结果值赋给例程参数之后。如果在严格SQL模式下定义例程,但在非严格模式下调用它,则不会在严格模式下将参数赋值给例程参数。如果要求以严格SQL模式分配传递给例程的表达式,则应该使用严格模式调用该例程。

评论characteristic是一个MySQL扩展,可以用来描述存储的例程。命令显示此信息显示创建过程而且显示创建函数语句。

语言特征指示编写例程所用的语言。服务器忽略这个特性;只支持SQL例程。

例程被认为是确定的如果它总是对相同的输入参数产生相同的结果,那么不确定性否则。如果既不确定的也不不确定性是在例程定义中给出的,默认是不确定性.要声明一个函数是确定的,必须指定确定的明确。

对套路性质的评估是基于诚实MySQL不检查已声明的例程确定的不包含产生不确定结果的语句。然而,错误地声明一个例程可能会影响结果或性能。将一个不确定例程声明为确定的可能导致优化器做出不正确的执行计划选择,从而导致意想不到的结果。将一个确定性例程声明为不确定的可能会导致不使用可用的优化,从而降低性能。

如果启用了二进制日志记录,则确定的特性影响MySQL接受哪些例程定义。看到第25.7节“存储程序二进制日志记录”

类的例程现在()函数(或其同义词)或RAND ()不确定,但还是可以复制的。为现在(),二进制日志包括时间戳并正确复制。RAND ()也可以正确复制,只要在例程执行期间只调用一次。(您可以将例程执行时间戳和随机数种子视为源和副本上相同的隐式输入。)

有几个特征提供了关于例程使用数据的性质的信息。在MySQL中,这些特征只是建议的。服务器不使用它们来约束一个例程允许执行哪些类型的语句。

  • 包含SQL指示例程不包含读取或写入数据的语句。如果没有显式给出这些特征,这是默认值。这种说法的例子是SET @x = 1RELEASE_LOCK (abc),执行但不读也不写数据。

  • 没有SQL表示该例程不包含SQL语句。

  • 读取SQL数据指示例程包含读取数据的语句(例如,选择),而不是写入数据的语句。

  • 修改SQL数据指示例程包含可能写入数据的语句(例如,插入删除).

SQL安全特征可以是定义者调用程序指定安全上下文;也就是说,该例程是否使用例程中指定的帐户的特权执行定义者子句或调用它的用户。此帐户必须具有访问与例程关联的数据库的权限。默认值为定义者.调用例程的用户必须具有执行特权为之,必须为之定义者如果例程在定义器安全上下文中执行,则指定帐户。

定义者子句指定在例程执行时检查访问权限时使用的MySQL帐户SQL安全定义器的特点。

如果定义者子句存在时,则用户值应该是MySQL帐户指定为user_name“@”host_name,CURRENT_USER,或CURRENT_USER ().允许用户值取决于您所拥有的特权,如中所讨论的第25.6节“存储对象访问控制”.有关存储例程安全性的其他信息,请参见该部分。

如果定义者子句时,默认定义者是执行创建过程创建函数声明。这和指定是一样的Definer = current_user明确。

类定义的存储例程主体中的SQL安全定义器特点,CURRENT_USER函数返回例程的定义者价值。有关存储例程中的用户审计的信息,请参见第6.2.22节“基于sql的帐户活动审计”

方法中列出的MySQL帐户数量的计数,请考虑下面的过程mysql.user系统表:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count() BEGIN SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;结束;

这个过程被分配了一个定义者账户的“admin”@“localhost”无论哪个用户定义它。无论哪个用户调用它,它都使用该帐户的特权执行(因为默认的安全特征是定义者).过程的成功或失败取决于调用方是否具有执行它的特权“admin”@“localhost”选择特权mysql.user表格

现在假设过程是用SQL安全调用程序特点:

CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count() SQL SECURITY INVOKER BEGIN SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;结束;

这个程序仍然有一个定义者“admin”@“localhost”,但在本例中,它使用调用用户的特权执行。因此,过程的成功或失败取决于调用方是否具有执行特权为它和选择特权mysql.user表格

服务器处理例程参数的数据类型,用于创建的本地例程变量声明,或函数返回值,如下所示:

  • 检查赋值是否存在数据类型不匹配和溢出。在严格SQL模式下,转换和溢出问题会导致警告或错误。

  • 只能分配标量值。例如,语句如SET x = (SELECT 1, 2)是无效的。

  • 对于字符数据类型,如果字符集,则使用指定的字符集及其默认排序规则。如果核对属性时,则使用该排序规则而不是默认排序规则。

    如果字符集而且核对不存在时,将使用例程创建时有效的数据库字符集和排序规则。为避免服务器使用数据库字符集和排序规则,请提供显式的字符集和一个核对属性用于字符数据参数。

    如果更改数据库默认字符集或排序规则,则必须删除并重新创建要使用新的数据库默认值的存储例程。

    属性的值给出数据库字符集和排序规则character_set_database而且collation_database系统变量。有关更多信息,请参见第10.3.3节“数据库字符集和排序规则”