---
title: "存储程序的变量 - OceanBase 数据库 V4.5.0 | OceanBase 文档中心"
description: 存储程序的变量 在存储程序中可以使用系统变量和用户定义变量，存储程序可以使用 DECLARE 来定义局部变量，存储例程（过程和函数）可以声明参数，以在例程及其调用者之间传递值。 定义局部变量 使用 DECLARE 语句定义局部变量。局部变量可以在声明的时候指定默认值或者使用 SET 语句赋值。 定义存储程序中的局部变…
---
切换语言

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

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

# 存储程序的变量

更新时间：2026-03-07 17:57:59

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

在存储程序中可以使用系统变量和用户定义变量，存储程序可以使用 `DECLARE` 来定义局部变量，存储例程（过程和函数）可以声明参数，以在例程及其调用者之间传递值。

## 定义局部变量

使用 `DECLARE` 语句定义局部变量。局部变量可以在声明的时候指定默认值或者使用 `SET` 语句赋值。

定义存储程序中的局部变量时，`DECLARE` 语句通过 `DEFAULT` 子句为变量提供默认值。该默认值可以指定为表达式，而且不一定是常量。如果缺少 `DEFAULT` 子句，则初始值为 `NULL`。语法如下：

```sql
DECLARE var_name [, var_name] ... data_type [DEFAULT value]

```

其中，`data_type` 支持 SQL 数据类型。此外，PL 还兼容如下数据类型：

- `INT2`（内部转换为 `SMALLINT`）
 - `INT4`（内部转换为 `INT`）
 - `LONG`（内部转换为 `MEDIUMTEXT`）

不允许将 `DEFAULT` 值分配给存储过程或函数的参数和局部变量（例如，使用 `SET var_name=DEFAULT` 语句），这将导致语法报错。

使用 `SELECT INTO` 或使用打开游标的 `FETCH INTO` 语句可以将查询结果检索到局部变量中。

变量声明必须出现在游标或异常处理程序声明之前。局部变量名不区分大小写。允许的字符和引用规则与其他标识符相同。

## 局部变量作用范围和解析

有关局部变量的作用范围以及如何解析不明确名称的信息。

局部变量的作用范围是它所被声明的 `BEGIN END` 块中。该变量可以在声明块中的嵌套块中被引用，但不包括具有相同变量名称的块。

由于局部变量仅在存储程序执行期间有效，因此在存储程序内创建的 Prepared 语句中不允许引用这些局部变量。Prepared 语句的作用域是当前会话，而不是存储程序，因此该语句可以在程序结束后执行，此时变量将不会存在于作用域中。例如，`SELECT ... INTO local_var` 不能用作 Prepared 语句。此限制也适用于存储过程和函数参数。

#### 说明

局部变量不应与表的列名称相同。如果 SQL 语句，例如 `SELECT INTO` 语句，包含对列的引用的同时具有相同名称的已声明的局部变量，数据库将该引用解析为变量的名称。

如下示例中，数据库将 `SELECT` 语句中的 `vname` 解析为对 `vname` 变量的引用，而不是对 `vname` 列的引用。因此，当调用存储过程 `proc1()` 时，无论 `tbl1.vname` 的值是多少，`newname` 变量都会返回值"`OceanBase`"。

```sql
obclient> DELIMITER //

obclient> CREATE PROCEDURE proc1 (x VARCHAR(10))
    BEGIN
      DECLARE vname VARCHAR(10) DEFAULT 'OceanBase';
      DECLARE newname VARCHAR(10);
      DECLARE xid INT;

      SELECT vname, id INTO newname, xid
        FROM tbl1 WHERE vname = vname;
      SELECT newname;
    END //
Query OK, 0 rows affected

```

类似地，以下示例的存储过程中的游标定义包含的 `SELECT` 语句引用了 `vname`。数据库将其解析为对该名称对应变量的引用，而不是列引用。

```sql
obclient> CREATE PROCEDURE proc2 (x VARCHAR(10))
    BEGIN
      DECLARE vname VARCHAR(10) DEFAULT 'OceanBase';
      DECLARE newname VARCHAR(10);
      DECLARE xid INT;
      DECLARE done TINYINT DEFAULT 1;
      DECLARE curdo CURSOR FOR SELECT vname, id FROM tbl1;
      DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 0;

      OPEN curdo;
      readlable1: LOOP
        FETCH FROM curdo INTO newname, xid;
        IF done THEN LEAVE readlable1; END IF;
        SELECT newname;
      END LOOP;
      CLOSE curdo;
    END //
Query OK, 0 rows affected

```

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