---
title: "存储过程 - OceanBase 数据库 V4.4.0 | OceanBase 文档中心"
description: "存储过程 存储过程是一种没有直接返回值的子程序。当参数类型为 OUT 时，存储过程也可以给调用者返回值。 存储过程的结构 一个 PL 存储过程的结构如下： PROCEDURE sp_name ([proc_parameter[,...]])[characteristic ...] BEGIN -- 开始执行 SQL …"
---
切换语言

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

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

# 存储过程

更新时间：2025-09-06 16:39:58

[编辑](https://github.com/oceanbase/oceanbase-doc/edit/V4.4.0/zh-CN/700.reference/600.pl-reference/200.pl-mysql/200.storage-object-mysql/300.pl-stored-procedure-mysql.md)  

存储过程是一种没有直接返回值的子程序。当参数类型为 `OUT` 时，存储过程也可以给调用者返回值。

## 存储过程的结构

一个 PL 存储过程的结构如下：

```sql
PROCEDURE sp_name ([proc_parameter[,...]])[characteristic ...]
    BEGIN    -- 开始执行
      SQL statement; [ SQL statement; ]...
    END;     -- 结束执行

proc_parameter:
    [ IN | OUT | INOUT ] param_name type

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

```

## 存储过程的创建

存储过程通过 `CREATE PROCEDURE` 语句创建存储过程。MySQL 模式下与 Oracle 模式比较显著的区别如下：

- `DECLARE` 模块要放在 `BEGIN ... END;` 模块中，并且所有定义声明完成后才能定义其他语句。
 - 可以定义 `DETERMINISTIC / LANGUAGE SQL` 等 `sp_create_chistic` 信息以丰富存储过程的使用。
 - MySQL 模式下的存储过程不存在重载情况。

**示例 1：创建不带有 `IN` 和 `OUT` 参数的存储过程。**

```sql
obclient> DELIMITER //

obclient> CREATE PROCEDURE proc_name()
   BEGIN
     DECLARE var_name VARCHAR(20) DEFAULT 'ZhangSan';  
     SET var_name = 'LiSi';
     SELECT var_name;
   END //
Query OK, 0 rows affected

obclient> DELIMITER ;

obclient> CALL proc_name();

```

返回结果如下所示：

```shell
+----------+
| var_name |
+----------+
| LiSi     |
+----------+
1 row in set

```

**示例 2：创建带有 `IN` 和 `OUT` 参数的存储过程。**

```sql
//创建示例表 emp
obclient> CREATE TABLE emp(  
   empno          NUMBER(4,0),  
   empname        VARCHAR(10),  
   job            VARCHAR(10),
   deptno         NUMBER(2,0),
   salary         NUMERIC  
);
Query OK, 0 rows affected

obclient> INSERT INTO emp VALUES (200,'Jennifer','AD_ASST',1,15000),(202,'Pat','MK_REP',2,12000),
          (119,'Karen','PU_CLERK', 4,10000),(118,'Guy','PU_CLERK', 4,10000),
         (201,'Michael','MK_MAN',3,9000);
Query OK, 5 rows affected
Records: 5  Duplicates: 0  Warnings: 0

obclient> DELIMITER //

obclient> CREATE PROCEDURE my_proc(IN emp_no INT,OUT emp_count INT)
   BEGIN
     SELECT COUNT(*) INTO emp_count FROM emp WHERE empno=emp_no;
   END //
Query OK, 0 rows affected

//初始化参数
obclient> SET @emp_no='200',@emp_count=0;
Query OK, 0 rows affected

//调用存储过程 my_proc
obclient> CALL my_proc(@emp_no,@emp_count);

```

返回结果如下所示：

```shell
+-----------+
| emp_count |
+-----------+
|         1 |
+-----------+
1 row in set

```

继续查看 emp_count 被赋值后的结果：

```sql
obclient> SELECT @emp_count;

```

返回结果如下所示：

```shell
+------------+
| @emp_count |
+------------+
| 1          |
+------------+
1 row in set

```

## 存储过程的调用

已创建的存储过程，需要使用 `CALL` 语句来调用，但是它不能作为 SQL 表达式的一部分被调用。

```sql
//调用存储过程 my_proc
obclient> CALL my_proc(@emp_no,@emp_count);
Query OK, 0 rows affected

//查看 emp_count 被赋值后的结果

obclient> SELECT @emp_count;

```

返回结果如下所示：

```

 上一篇 下一篇 ![有帮助](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) 咨询热线
