---
title: "CREATE FUNCTION - OceanBase 数据库 V4.4.0 | OceanBase 文档中心"
description: CREATE FUNCTION 描述 CREATE FUNCTION 语句用于创建存储函数。 权限要求 使用 CREATE PROCEDURE 语句拥有 CREATE FUNCTION 权限。 基本示例： 将权限 CREATE ROUTINE 赋权给用户后，用户可以创建 FUNCTION 。 -- 创建用户并授权 o…
---
切换语言

- 中文站 - 简体中文
- International - English
- 日本站 - 日本語

文档反馈![](https://mdn.alipayobjects.com/huamei_22khvb/afts/img/A*P8CuR4UJ_FkAAAAAAAAAAAAADiGDAQ/original) OceanBase 数据库分布式版 - V 4.4.0

# CREATE FUNCTION

更新时间：2025-08-19 18:39:03

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.4.0/zh-CN/700.reference/600.pl-reference/200.pl-mysql/600.sql-statements-for-pl-stored-programs-mysql/500.create-function-mysql.md)  

## 描述

`CREATE FUNCTION` 语句用于创建存储函数。

## 权限要求

使用 `CREATE PROCEDURE` 语句拥有 `CREATE FUNCTION` 权限。

**基本示例：**

将权限 `CREATE ROUTINE` 赋权给用户后，用户可以创建 `FUNCTION`。

```sql
-- 创建用户并授权
obclient> CREATE USER 'mingye'@'localhost' IDENTIFIED BY 'password';
obclient> GRANT CREATE ROUTINE ON mydb.* TO 'mingye'@'localhost';
obclient> GRANT EXECUTE ON mydb.* TO 'mingye'@'localhost';

-- 切换到目标数据库
obclient> USE mydb;

-- 创建函数
obclient> DELIMITER //
obclient> CREATE FUNCTION add_numbers(a INT, b INT)
    RETURNS INT
    DETERMINISTIC
    BEGIN
        RETURN a + b;
    END //
obclient> DELIMITER ;

-- 测试函数
obclient> SELECT add_numbers(5, 3);

```

默认情况下，在创建完 `PROCEDURE` 之后，OceanBase 数据库自动将 `ALTER ROUTINE` 和 `EXECUTE` 权限授予例程（存储过程和函数）创建者。如果存在 `DEFINER` 子句，则所需的权限取决于 `user` 的值。

**使用 DEFINER 子句的示例：**

```sql
-- 创建管理员用户
obclient> CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin_password';
obclient> GRANT ALL PRIVILEGES ON mydb.* TO 'admin'@'localhost';

-- 创建普通用户
obclient> CREATE USER 'user1'@'localhost' IDENTIFIED BY 'user_password';
obclient> GRANT SELECT, EXECUTE ON mydb.* TO 'user1'@'localhost';

-- 使用 DEFINER 创建函数
obclient> DELIMITER //
obclient> CREATE DEFINER='admin'@'localhost' FUNCTION multiply_numbers(a INT, b INT)
    RETURNS INT
    DETERMINISTIC
    BEGIN
        RETURN a * b;
    END //
obclient> DELIMITER ;

-- 以普通用户身份测试函数
obclient> SELECT multiply_numbers(4, 6);

```

## 语法

```sql
CREATE
    [DEFINER = user]
    FUNCTION [IF NOT EXISTS] sp_name ([func_parameter[,...]])
    RETURNS type
    [characteristic ...] routine_body

func_parameter:
    param_name type

type:
    Any valid MySQL data type

characteristic: {
    COMMENT 'string'
  | LANGUAGE SQL
  | [NOT] DETERMINISTIC
  | { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
  | SQL SECURITY { DEFINER | INVOKER }
}

routine_body:
    Valid SQL routine statement

```

默认情况下，存储函数与默认数据库相关联。要将存储函数与指定数据库的相关联，请使用 `database_name.sp_name` 指定名称。

要调用存储函数，可以在表达式中引用该函数。该函数在表达式求值期间返回一个值。

`DEFINER` 和 `SQL SECURITY` 子句指定在例程执行时检查访问权限要使用的安全上下文。

`IF NOT EXISTS` 防止创建已经存在的同名例程。如果存储名称与内置 SQL 函数的名称相同，则会发生语法错误，除非在定义例程或稍后调用例程时在名称和随后的括号之间使用空格。因此，请避免使用现有 SQL 函数的名称创建用户自己的存储例程。

括号内的 `proc_parameter` 参数列表必须始终存在。如果没有参数，则应使用空括号 `()` 表示空参数列表。这里的参数名称不区分大小写。对于存储函数的每个参数都是 `IN` 参数。

`RETURNS` 子句只用于存储函数，用于指定函数的返回类型，函数包体必须包含 `RETURN value` 语句。如果 `RETURN` 语句返回不同类型的值，则该值将强制转换为合适的类型。例如，如果函数在 `RETURNS` 子句中指定了 `ENUM` 或者 `SET` 值，但 `RETURN` 语句返回整数，则从函数返回的值是 `SET` 成员集合中相应 `ENUM` 成员的字符串。

参数类型和函数返回类型可以声明为任何有效的数据类型，如果前面带有 `CHARACTER SET`，则可以使用 `COLLATE` 属性。

`routine_body` 由有效的 SQL 语句组成。SQL 语句可以是一个简单的语句，例如 `SELECT` 或 `INSERT`，也可以是使用由 `BEGIN` 和 `END` 编写的复合语句。复合语句可以包含声明、循环和其他控制结构语句。实际上，存储函数倾向于使用复合语句，除非主体由单个 `RETURN` 语句组成。

不允许在存储例程中使用 `USE` 语句。调用例程时，将隐式执行 `USE database_name`（并在例程终止时撤消），为执行例程指定默认数据库。如果要引用例程默认数据库以外的其他数据库对象，可以使用数据库名称进行限定。

如果在严格 SQL 模式下定义例程，却在非严格模式下调用它，则不会在严格模式下为例程的参数赋值。如果在严格 SQL 模式下分配传递给例程的表达式，则应在严格模式下调用例程。

`COMMENT` 特性可以用来描述存储的例程，使用 `SHOW CREATE PROCEDURE` 和 `SHOW CREATE FUNCTION` 语句可以显示注释信息。

`LANGUAGE` 特性表示编写例程所用的语言。仅适用于 SQL 例程，服务器会忽略此特征。

如果一个例程总是对相同的输入参数产生相同的结果，那么它被认为是"确定性的"，否则就被认为是"不确定性的"。如果例程定义中既没有给出 `DETERMINISTIC` 也没有给出 `NOT DETERMINISTIC`，则默认为 `NOT DETERMINISTIC`。要声明函数是确定性的，必须显式指定 `DETERMINISTIC`。

有关例程使用数据的特性信息如下：

- `CONTAINS SQL` 表示例程不包含读写数据的语句，这是默认值。例如，`SET@x=1` 或 `DO RELEASE_LOCK('abc')` 会被执行但既不读取也不写入数据。
 - `NO SQL` 表示例程不包含 SQL 语句。
 - `READS SQL DATA` 表示例程包含读取数据的语句（例如 `SELECT`），但不包含写入数据的语句。
 - `MODIFIES SQL DATA` 表示例程包含可能写入数据的语句（例如 `INSERT` 或 `DELETE`）。

`SQL SECURITY` 可以是 `DEFINER` 或 `INVOKER`，来指定例程是使用指定账号（此账号必须具有访问与例程关联的数据库的权限）的权限执行，还是使用调用者的权限执行。默认值为 `DEFINER`。调用例程的用户必须具有该例程的 `EXECUTE` 权限。

`DEFINER` 子句指定在例程执行检查例程的访问权限时所使用的账号。如果存在 `DEFINER` 子句，则 `user` 值应为指定为 `'user_name'@'host_name'` 的账号（例如 `'admin'@'oblocalhost'`）或者由 `CURRENT_USER()` 函数获取的账户。如果省略 `DEFINER` 子句，则默认定义者是执行 `CREATE FUNCTION` 语句的用户。在使用 `SQL SECURITY DEFINER` 特性定义的存储例程的主体中，可以使用 `CURRENT_USER` 函数返回例程的 `DEFINER` 值。

服务器对例程参数、使用 `DECLARE` 创建的本地例程变量或函数返回值的数据类型的处理方式如下：

- 检查是否存在数据类型不匹配和溢出。转换和溢出问题会导致在严格 SQL 模式下出现告警或错误。
 - 只能指定标量值。例如 `SET val=(SELECT 1, 2)` 语句是无效的。
 - 对于字符数据类型，如果声明中包含 `CHARACTER SET`，则使用指定的字符集及其默认排序规则。如果使用了 `COLLATE` 属性，则使用指定的排序规则，而不使用默认排序规则。

  如果不存在 `CHARACTER SET` 和 `COLLATE`，则使用在例程创建时应用的数据库字符集和排序规则。为避免服务器使用数据库字符集和排序规则，请为参数显式指定 `CHARACTER SET` 和 `COLLATE` 特性。

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

  `character_set_database` 和 `collation_database` 系统变量可以用于指定数据库字符集和排序规则。

有关创建函数的详细示例信息，请参见 [存储函数](https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000003381090)。

 上一篇 下一篇 ![有帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*y6ocSqN8cqsAAAAAAAAAAAAAARQnAQ)![无帮助](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*BG9IQJyLHF8AAAAAAAAAAAAAARQnAQ)![反馈](https://gw.alipayobjects.com/mdn/ob_asset/afts/img/A*eTWdQKCRKHwAAAAAAAAAAAAAARQnAQ)[AI](https://www.oceanbase.com/obi) 咨询热线
