为什么我们在匿名块的最后部分需要 BEGIN END(执行部分)?

Why do we need BEGIN END (execution section) in last portion for an Anonymus block?

当我尝试运行这段代码时

DECLARE
TYPE type_a IS
    TABLE OF NUMBER INDEX BY PLS_INTEGER;
output NUMBER := 1;

FUNCTION fun_2 RETURN type_a IS
    dum type_a;
BEGIN
    SELECT
        employee_id
    BULK COLLECT
    INTO dum
    FROM
        employees;

    RETURN dum;
END fun_2;

PROCEDURE proc_1 AS
BEGIN
    NULL;
END;

我遇到以下错误:

Error report - ORA-06550: line 22, column 8: PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:

begin function pragma procedure 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:

但是当我最后添加 BEGIN END 时它工作正常

    DECLARE
    TYPE type_a IS
        TABLE OF NUMBER INDEX BY PLS_INTEGER;
    output NUMBER := 1;

    FUNCTION fun_2 RETURN type_a IS
        dum type_a;
    BEGIN
        SELECT
            employee_id
        BULK COLLECT
        INTO dum
        FROM
            employees;

        RETURN dum;
    END fun_2;

    PROCEDURE proc_1 AS
    BEGIN
        NULL;
    END;

BEGIN
    null ;
END;

我得到了答案,但这是为什么呢?我的意思是代码是如何执行的,为什么需要它?

PL/SQL 块具有结构 DECLARE ... BEGIN ... END;。如果要声明任何变量等,DECLARE 是可选的,但 BEGIN ... END; 是必需的。

如果我们从一个简单的块开始并构建:

BEGIN
  NULL;
END;
/

是最简单的PL/SQL语句。然后声明一个类型:

DECLARE
  TYPE type_a IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
BEGIN
  NULL;
END;
/

和一个变量:

DECLARE
  TYPE type_a IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  output NUMBER := 1;
BEGIN
  NULL;
END;
/

然后你DECLARE一个函数;这包括它自己的 PL/SQL BEGIN ... END; 块,它将嵌套在匿名外部块的 DECLARE 部分中:

DECLARE
  TYPE type_a IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  output NUMBER := 1;

  FUNCTION fun_2 RETURN type_a IS
    dum type_a;
  BEGIN
    SELECT employee_id
    BULK COLLECT INTO dum
    FROM employees;

    RETURN dum;
  END fun_2;
BEGIN
  NULL;
END;
/

然后你声明一个程序;这再次包括它自己的 PL/SQL BEGIN ... END; 块,它将嵌套在函数之后的匿名外部块的 DECLARE 部分中:

DECLARE
  TYPE type_a IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
  output NUMBER := 1;

  FUNCTION fun_2 RETURN type_a IS
    dum type_a;
  BEGIN
    SELECT employee_id
    BULK COLLECT INTO dum
    FROM employees;

    RETURN dum;
  END fun_2;

  PROCEDURE proc_1 AS
  BEGIN
    NULL;
  END proc_1;
BEGIN
  NULL;
END;
/

回到你的问题:

why is it needed?

因为,否则您有两个 BEGIN ... END; 块用于嵌套在 DECLARE 部分中的函数和过程,从第一行开始但没有 BEGIN ... END; 匹配 DECLARE 在第一行。

使用一致的缩进有助于发现这一点。