文档首页> 数据仓库服务 GaussDB(DWS)> 常见问题> 数据库使用> 函数和存储过程有什么区别?
更新时间:2023-10-12 GMT+08:00

函数和存储过程有什么区别?

函数和存储过程是数据库管理系统中常见的两种对象,它们在实现特定功能时具有相同点,也有不同点。了解它们的特点和适用场景,对于合理设计数据库结构和提高数据库性能具有重要意义。

表1 函数和存储过程的区别

函数

存储过程

两者都可以用于实现特定的功能。无论是函数还是存储过程,都可以封装一系列的SQL语句,以完成某些特定的操作。

两者都可以接收输入参数,并且根据参数的不同来进行相应的操作。

函数的标识符为FUNCTION。

存储过程的标识符为PROCEDURE。

函数必须返回一个具体的值,并且规定返回值的数值类型。

存储过程可以没有返回值,也可以有返回值,甚至可以有多个返回值,可以通过输出参数返回结果,也可以直接在存储过程中使用SELECT语句返回结果集。

函数适用于需要返回单个值的情况,比如计算某个数值、字符串处理、返回表等。

存储过程适用于需要执行DML操作的情况,比如批量插入、更新、删除数据等。

  • 创建并调用函数

    创建表emp并插入数据,查询表数据如下:

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM emp;
     empno | ename |   job    | mgr  |      hiredate       |   sal   |  comm  | deptno
    -------+-------+----------+------+---------------------+---------+--------+--------
      7369 | SMITH | CLERK    | 7902 | 1980-12-17 00:00:00 |  800.00 |        |     20
      7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 |     30
      7566 | JONES | MANAGER  | 7839 | 1981-04-02 00:00:00 | 2975.00 |        |     20
      7521 | WARD  | SALESMAN | 7698 | 1981-02-22 00:00:00 | 1250.00 | 500.00 |     30
    (4 rows)
    

    创建函数emp_comp,用于接受两个数字作为输入并返回计算值:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE OR REPLACE FUNCTION emp_comp (
        p_sal           NUMBER,
        p_comm          NUMBER
    ) RETURN NUMBER
    IS
    BEGIN
        RETURN (p_sal + NVL(p_comm, 0)) * 24;
    END;
    /
    

    使用SELECT命令调用函数:

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT ename "Name", sal "Salary", comm "Commission", emp_comp(sal, comm) "Total Compensation" FROM emp;
     Name  | Salary  | Commission | Total Compensation
    -------+---------+------------+--------------------
     SMITH |  800.00 |            |           19200.00
     ALLEN | 1600.00 |     300.00 |           45600.00
     JONES | 2975.00 |            |           71400.00
     WARD  | 1250.00 |     500.00 |           42000.00
    (4 rows)
    
  • 创建并调用存储过程

    创建表MATCHES并插入数据,查询表数据如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT * FROM MATCHES;
     matchno | teamno | playerno | won | lost
    ---------+--------+----------+-----+------
           1 |      1 |        6 |   3 |    1
           7 |      1 |       57 |   3 |    0
           8 |      1 |        8 |   0 |    3
           9 |      2 |       27 |   3 |    2
          11 |      2 |      112 |   2 |    3
    (5 rows)
    

    创建存储过程delete_matches,用于删除给定球员参加的所有比赛:

    1
    2
    3
    4
    5
    6
    CREATE PROCEDURE delete_matches(IN p_playerno INTEGER) 
    AS 
    BEGIN
       DELETE FROM MATCHES WHERE playerno = p_playerno;
    END;
    /
    

    调用存储过程delete_matches:

    1
    CALL delete_matches(57);
    

    再次查询表MATCHES,由返回结果可知,playerno为57的数据已被删除:

    1
    2
    3
    4
    5
    6
    7
    8
    SELECT * FROM MATCHES;
     matchno | teamno | playerno | won | lost
    ---------+--------+----------+-----+------
          11 |      2 |      112 |   2 |    3
           8 |      1 |        8 |   0 |    3
           1 |      1 |        6 |   3 |    1
           9 |      2 |       27 |   3 |    2
    (4 rows)
    

数据库使用 所有常见问题

more