PL/SQL 循环、自定义函数以及存储过程实例详解

 更新时间:2026年05月08日 14:56:07   作者:穆金秋  
文章主要介绍了PL/SQL的核心内容,包括循环结构(FOR、WHILE循环及控制语句)、自定义函数和存储过程,详细解释了各自的特点、应用场景和示例,并对比了函数和存储过程的区别,特别是强调了Oracle存储过程中的IS/AS关键字的必要性

本文系统梳理了PL/SQL三大核心内容:

  1. 循环结构:包括FOR循环(固定次数)、WHILE循环(条件判断)及BREAK/CONTINUE控制语句;
  2. 自定义函数:强调必须返回值的特性,演示了数值计算和业务查询两种应用场景;
  3. 存储过程:侧重数据处理流程封装,对比了与函数的关键差异(无返回值、不可SQL调用)。

特别指出存储过程中IS/AS关键字不可省略的语法要求,并提供了典型练习案例(质数判断、字符串处理等)。

适用于数据库开发人员快速掌握PL/SQL编程要点。

📘 一、循环结构

1. FOR 循环(最常用)

FOR I IN 起始值..结束值 LOOP
  循环体;
END LOOP;
  • I 自动从起始值递增到结束值,步长为 1
  • 适合已知循环次数的场景

for 循环的步长固定为1,不能更改。

在 PL/SQL 的 FOR 循环中,起始值..结束值 是一个闭区间,循环变量 I 会从起始值一直遍历到结束值,包括结束值本身

示例:判断质数

DECLARE
  X NUMBER := &请输入数值;
  V_FLAG NUMBER := 0;
BEGIN
  FOR I IN 2..X-1 LOOP
    IF MOD(X, I) = 0 THEN
      V_FLAG := 1;
    END IF;
  END LOOP;
  ...
END;

示例:99 乘法表

DECLARE
  V_STR VARCHAR2(100);
BEGIN
  FOR I IN 1..9 LOOP
    V_STR := '';
    FOR J IN 1..I LOOP
      V_STR := V_STR || I || ' * ' || J || ' = ' || I*J || ' ';
    END LOOP;
    DBMS_OUTPUT.PUT_LINE(V_STR);
  END LOOP;
END;

2. WHILE 循环

WHILE 条件 LOOP
  循环体;
  变量自增/自减;
END LOOP;
  • 适合未知循环次数,但知道结束条件的场景

示例:输出 1~100 奇数

DECLARE
  V_NUM NUMBER := 1;
BEGIN
  WHILE V_NUM <= 100 LOOP
    IF MOD(V_NUM,2) = 1 THEN
      DBMS_OUTPUT.PUT_LINE(V_NUM);
    END IF;
    V_NUM := V_NUM + 1;
  END LOOP;
END;

3. 循环控制语句(重要!)

关键字作用说明
BREAK终止当前循环,循环外代码继续执行
CONTINUE跳过本次循环剩余代码,进入下一次循环
RETURN直接结束整个程序(循环外代码也不执行)

📘 二、自定义函数(FUNCTION)

语法结构

CREATE OR REPLACE FUNCTION 函数名(入参名 参数类型)
RETURN 返回值类型
IS
  变量声明;
BEGIN
  逻辑体;
  RETURN 结果;
END;

特点

  • 必须有返回值
  • 入参和返回值类型不能定义长度
  • 适合封装常用计算逻辑

示例:模拟 ABS 函数

CREATE OR REPLACE FUNCTION ABS_BAK(P_NUM NUMBER)
RETURN NUMBER
IS
BEGIN
  RETURN REPLACE(P_NUM, '-');
END;

示例:根据员工编号返回姓名(带错误处理)

📘 三、存储过程(PROCEDURE)

语法结构

CREATE OR REPLACE PROCEDURE 过程名(入参名 参数类型)
IS
  变量声明;
BEGIN
  -- 数据同步、清洗、处理流程
END;

特点

  • 没有返回值
  • 适合封装数据处理流程(如 ETL)

示例:同步部门最高薪资

CREATE OR REPLACE PROCEDURE P_001
IS
BEGIN
  DELETE FROM H_SAL_EMP;
  INSERT INTO H_SAL_EMP
  SELECT DEPTNO, MAX(SAL) FROM EMP GROUP BY DEPTNO;
  COMMIT;
END;

调用方式

BEGIN
  P_001;
END;

示例:带参数的过程

CREATE OR REPLACE PROCEDURE P_002(C_JOB VARCHAR2)
IS
BEGIN
  DELETE FROM EMP_J WHERE JOB = C_JOB;
  INSERT INTO EMP_J SELECT * FROM EMP WHERE JOB = C_JOB;
  COMMIT;
END;

📘 四、函数 vs 存储过程(面试/考试重点)

对比项函数(FUNCTION)存储过程(PROCEDURE)
返回值必须有没有
语法关键字FUNCTIONPROCEDURE
使用场景计算并返回一个值封装数据同步、处理流程
能否在 SQL 中直接调用✅ 可以(如 SELECT 函数名()❌ 不可以
是否必须有 RETURN✅ 是❌ 否

Oracle 存储过程 procedure 不允许使用 return 语句

✅ 典型练习题(建议手动敲一遍)

1. 循环练习

  • 使用 FOR / WHILE 计算 1~200 之间所有偶数的和
  • 打印 1~X 之间所有的质数

2. 函数练习

-- 实现 ELIM 函数:删除字符串中第一次出现的指定字符
-- 示例:ELIM('A-B-C', '-') → 'AB-C'

3. 存储过程练习

-- 创建表 T_NUMBER(ID NUMBER)
-- 创建过程 P_004(X),将比 X 小的所有奇数插入 T_NUMBER
create TABLE T_NUMBER(
ID NUMBER
);
commit;
CREATE OR REPLACE PROCEDURE p_004(x NUMBER)
      IS
      BEGIN
        -- 清空表格
        DELETE FROM T_NUMBER;
        COMMIT;
        -- 或者使用 TRUNCATE(更高效,但无法回滚)
        -- EXECUTE IMMEDIATE 'TRUNCATE TABLE T_NUMBER';
        for i in 1..x-1 loop
            if mod(i,2)=1
            then
            INSERT INTO T_NUMBER(ID) VALUES (i);
            end if;
        end loop;
        COMMIT;
      END;
-- 调用存储过程
BEGIN
p_004(100);
END;
select * from T_NUMBER;

补充:IS可以省略不写吗

在 Oracle 存储过程中,IS(或 AS)是必须的,不能省略。

存储过程的基本语法结构:

CREATE OR REPLACE PROCEDURE 过程名(参数)
IS      -- 或 AS,必须存在,不能省略
BEGIN
    -- 过程体
END;
/

IS 和 AS 的区别:

在存储过程中,IS 和 AS 完全等价,可以互换使用:

-- 使用 IS
CREATE OR REPLACE PROCEDURE p_004(x NUMBER) 
IS
BEGIN
    -- 逻辑
END;
-- 使用 AS(同样正确)
CREATE OR REPLACE PROCEDURE p_004(x NUMBER) 
AS
BEGIN
    -- 逻辑
END;

为什么不能省略?

IS/AS 的作用是:

  • 标记声明部分的开始(用于声明变量、游标等)
  • 分隔过程头部和主体
  • 语法规定的必需关键字
-- 错误示范(缺少 IS/AS)
CREATE OR REPLACE PROCEDURE p_004(x NUMBER)  -- 编译错误!
BEGIN
    NULL;
END;

对比其他数据库:

数据库语法IS/AS 是否必需
OracleIS 或 AS必需
SQL ServerAS必需
PostgreSQLAS必需(但写法不同)
MySQL不需要不需要

总结:在 Oracle 中创建存储过程,IS 或 AS 是必需的关键字,不能省略。如果没有任何变量声明,可以在 IS 后直接写 BEGIN

到此这篇关于PL/SQL 循环、自定义函数以及存储过程实例详解的文章就介绍到这了,更多相关PL/SQL 循环 自定义函数存储过程内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • centos虚拟机部署opengauss数据库详细图文教程

    centos虚拟机部署opengauss数据库详细图文教程

    这篇文章主要给大家介绍了关于centos虚拟机部署opengauss数据库的相关资料,文章详细介绍了在CentOS上安装和配置openGauss数据库的过程,包括安装步骤、环境配置、权限设置、预安装和正式安装等,需要的朋友可以参考下
    2024-12-12
  • 关于sql注入的简要演示(入坑抛砖)

    关于sql注入的简要演示(入坑抛砖)

    这篇文章主要介绍了关于sql注入的简要演示(入坑抛砖),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • sql Union和Union All的使用方法

    sql Union和Union All的使用方法

    UNION指令的目的是将两个SQL语句的结果合并起来。从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料。
    2009-07-07
  • 通过一分钟快速了解索引技巧

    通过一分钟快速了解索引技巧

    这篇文章主要给大家介绍了如何通过一分钟快速了解索引技巧的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用索引具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-12-12
  • Hive如何写exist/in子句示例详解

    Hive如何写exist/in子句示例详解

    这篇文章主要介绍了在Hive中使用EXISTS和IN子句进行数据查询的方法,EXISTS子句用于检查子查询是否至少返回一行记录,而IN子句用于检查某个值是否存在于指定的列表中,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-02-02
  • 数据库命名规范小结

    数据库命名规范小结

    数据库命名规范,在实际的数据库开发中,需要注意。
    2009-03-03
  • windows安装Neo4j图数据库的详细过程

    windows安装Neo4j图数据库的详细过程

    本文介绍了在Windows上安装和配置Neo4j图数据库的步骤,包括安装JavaSDK、解压安装Neo4j、配置环境变量、启动数据库以及服务化启动,感兴趣的朋友一起看看吧
    2025-03-03
  • 为什么你不要收缩数据库文件(国外翻译)

    为什么你不要收缩数据库文件(国外翻译)

    这几天查看了很多关于SQL SERVER收缩数据文件方面的文章,准备写一篇关于收缩日志方面的文章,但是突然有种冲动将看过经典的文章翻译出来,需要的朋友可以参考下
    2018-03-03
  • update 子查询使用介绍

    update 子查询使用介绍

    这篇文章主要介绍了update 子查询使用介绍,需要的朋友可以参考下
    2014-08-08
  • 数据库触发器Trigger详解

    数据库触发器Trigger详解

    在数据库管理系统中,触发器(Trigger)是一种特殊的存储过程,它在特定的事件发生时自动执行,本文给大家介绍数据库触发器Trigger的相关知识,感兴趣的朋友一起看看吧
    2025-05-05

最新评论