相关的文档10bet官方网站 本手册下载 本手册节选

9.2.5函数名解析与解析

MySQL支持内置(本机)函数、用户定义函数(udf)和存储函数。本节描述服务器如何识别内置函数的名称是用作函数调用还是用作标识符,以及当存在具有给定名称的不同类型函数时,服务器如何确定使用哪个函数。

内置函数名解析

解析器使用默认规则解析内置函数的名称。的方法可以更改这些规则IGNORE_SPACESQL模式。

当解析器遇到内置函数名称的单词时,它必须确定该名称表示函数调用,还是对标识符(如表或列名)的非表达式引用。例如,在以下语句中,第一个引用是一个函数调用,而第二个引用是一个表名:

SELECT COUNT(*) FROM mytableCREATE TABLE count (i INT);

只有在解析预期的表达式时,解析器才应该将内置函数的名称识别为指示函数调用的名称。也就是说,在非表达式上下文中,允许函数名作为标识符。

然而,一些内置函数有特殊的解析或实现考虑,因此解析器默认使用以下规则来区分它们的名称是用作函数调用还是用作非表达式上下文中的标识符:

  • 若要在表达式中将名称用作函数调用,则名称与以下内容之间不能有空格括号字符。

  • 相反,要使用函数名作为标识符,它后面不能紧跟着圆括号。

函数调用时在名称和圆括号之间不使用空格的要求只适用于有特殊考虑的内置函数。就是这样一个名字。的sql / lex.h源文件列出了这些特殊函数的名称,下面的空格决定了它们的解释SYM_FN ()宏观的符号[]数组中。

下面列出了MySQL 8.0中受IGNORE_SPACE设置并列为特殊sql / lex.h源文件。您可能会发现,将无空格要求视为应用于所有函数调用是最容易的。

  • ADDDATE

  • BIT_AND

  • BIT_OR

  • BIT_XOR

  • CURDATE

  • CURTIME

  • DATE_ADD

  • DATE_SUB

  • 提取

  • GROUP_CONCAT

  • 马克斯

  • 中期

  • 最小值

  • 现在

  • 位置

  • 为SESSION_USER

  • 性病

  • STDDEV

  • STDDEV_POP

  • STDDEV_SAMP

  • SUBDATE

  • 字符串的子串

  • 子字符串

  • 总和

  • SYSDATE

  • SYSTEM_USER

  • 修剪

  • 方差

  • VAR_POP

  • VAR_SAMP

中未列为特殊的函数sql / lex.h,空格不重要。只有在表达式上下文中使用时,它们才被解释为函数调用,否则可以随意用作标识符。美国信息交换标准代码就是这样一个名字。然而,对于这些不受影响的函数名,表达式上下文的解释可能不同:func_name()如果有一个具有给定名称的函数,则被解释为内置函数;如果不是这样,func_name()被解释为用户定义函数或存储函数(如果存在同名函数)。

IGNORE_SPACESQL模式可以用来修改解析器如何处理对空格敏感的函数名:

  • IGNORE_SPACE禁用后,当名称和下面的括号之间没有空格时,解析器将名称解释为函数调用。即使在非表达式上下文中使用函数名也会发生这种情况:

    CREATE TABLE count(i INT);错误1064(42000):你有一个错误的SQL语法…数(INT)的附近

    为了消除错误并使名称被视为标识符,可以在名称后面使用空格或将其写为带引号的标识符(或两者都):

    CREATE TABLE count (i INT);创建表count (INT);创建表count (INT);
  • IGNORE_SPACE启用后,解析器放宽了函数名和后面括号之间不存在空格的要求。这为编写函数调用提供了更大的灵活性。例如,以下函数调用都是合法的:

    SELECT COUNT(*) FROM mytableSELECT COUNT (*) FROM mytable

    然而,使IGNORE_SPACE还有一个副作用,解析器将受影响的函数名作为保留字处理(参见第9.3节“关键词和保留词”).这意味着名称后面的空格不再表示它用作标识符。该名称可以在带有或不带有后面空格的函数调用中使用,但在非表达式上下文中会导致语法错误,除非用引号括起来。例如,使用IGNORE_SPACE启用后,由于解析器的解释,以下两条语句都会失败并出现语法错误作为保留词:

    CREATE TABLE count(i INT);CREATE TABLE count (i INT);

    要在非表达式上下文中使用函数名,请将其写为带引号的标识符:

    创建表count (INT);创建表count (INT);

要启用IGNORE_SPACESQL模式下,使用以下语句:

设置sql_mode = 'IGNORE_SPACE';

IGNORE_SPACE也可以由某些其他复合模式启用,例如ANSI包括在他们的价值中:

SET sql_mode = 'ANSI';

检查第5.1.11节,“Server SQL模式”,以查看启用了哪些组合模式IGNORE_SPACE

来减少SQL代码对IGNORE_SPACE设置时,使用以下指导原则:

  • 避免创建与内置函数同名的udf或存储函数。

  • 避免在非表达式上下文中使用函数名。例如,这些语句使用受影响的函数名之一IGNORE_SPACE),因此在名称if后面有或没有空格时,它们都会失败IGNORE_SPACE启用:

    CREATE TABLE count(i INT);CREATE TABLE count (i INT);

    如果你必须在非表达式上下文中使用函数名,请将其写为带引号的标识符:

    创建表count (INT);创建表count (INT);

函数名称解析

以下规则描述了服务器如何解析对函数名的引用,以创建和调用函数:

  • 内置函数和用户定义函数

    如果试图创建与内置函数同名的UDF,则会出错。

  • 内置函数和存储函数

    可以创建具有与内置函数相同名称的存储函数,但要调用存储函数,必须使用模式名限定它。例如,如果创建一个名为π测验模式,调用它为test.PI ()因为服务器解析π()没有限定符作为对内置函数的引用。如果存储的函数名与内置的函数名冲突,服务器会生成一个警告。可以显示警告显示警告

  • 用户定义函数和存储函数

    用户定义函数和存储函数共享相同的命名空间,因此不能创建具有相同名称的UDF和存储函数。

上述函数名解析规则对升级到实现新内置函数的MySQL版本有一定的影响:

  • 如果您已经创建了具有给定名称的用户定义函数,并将MySQL升级到实现具有相同名称的新内置函数的版本,则无法访问UDF。要纠正这个错误,请使用删除函数放弃UDF和创建函数使用不同的非冲突名称重新创建UDF。然后修改任何受影响的代码以使用新名称。

  • 如果MySQL的新版本实现了一个与现有存储函数同名的内置函数,那么您有两种选择:重命名存储函数以使用不冲突的名称,或者更改对函数的调用,使它们使用模式限定符(即使用schema_namefunc_name()语法)。在这两种情况下,相应地修改任何受影响的代码。