怀念 Oracle 的匿名块?其实 PostgreSQL 用起来一样很爽!

数据库 PostgreSQL
PostgreSQL 支持类似于 Oracle 匿名块的功能。在 PostgreSQL 中,您可以使用 PL/pgSQL 的DO语句将未存储在数据库中的 PL/pgSQL 代码作为独立代码段运行。

Oracle PL/SQL 是 SQL 的过程式扩展。PL/SQL 的程序结构将代码划分为由以下关键字区分的块:DECLARE、BEGIN、EXCEPTION和END。未命名的 PL/SQL 代码块(未作为过程、函数或包存储在数据库中的代码)称为匿名块。

Oracle 用法

匿名块作为 Oracle PL/SQL 的基本单元,包含以下代码部分:

  • • 声明性部分(可选)— 包含变量(名称、数据类型和初始值)。
  • • 可执行部分(必填) — 包含可执行语句(每个块结构必须至少包含一个可执行的 PL/SQL 语句)。
  • • 异常处理部分(可选)— 包含用于处理代码中的异常或错误的元素。

例子:

Oracle 匿名块的简单结构。

SET SERVEROUTPUT ON;
BEGIN
  DBMS_OUTPUT.PUT_LINE('hello world');
END;
/
hello world
PL/SQL procedure successfully completed.

Oracle PL/SQL 匿名块可以包含高级代码元素,例如函数、游标、动态 SQL 和条件逻辑。以下匿名块使用了游标、条件逻辑和异常处理。

SET SERVEROUTPUT ON;
DECLARE
  v_sal_chk        NUMBER;
  v_emp_work_years NUMBER;
  v_sql_cmd        VARCHAR2(2000);
BEGIN
  FOR v IN (SELECT EMPLOYEE_ID, FIRST_NAME ||' '|| LAST_NAME AS
    EMP_NAME, HIRE_DATE, SALARY FROM EMPLOYEES)
  LOOP
    v_emp_work_years := EXTRACT(YEAR FROM SYSDATE)- EXTRACT (YEAR FROM v.hire_date);
    IF v_emp_work_years >=10and v.salary <=6000then
      DBMS_OUTPUT.PUT_LINE('Consider a Bonus for: '|| v.emp_name);
END IF;
END LOOP;
EXCEPTION WHEN OTHERS THEN
  DBMS_OUTPUT.PUT_LINE('CODE ERR: '|| sqlerrm);
END;
/

前面的示例根据表EMPLOYEES的列HIRE_DATE计算每个雇员的工作年数。如果员工工作了十年或更长时间,工资为 6000 美元或更低,系统会打印消息“考虑奖金:<员工姓名>”。

有关详细信息,请参阅 Oracle 文档中的 PL/SQL 概述。

PostgreSQL 用法

PostgreSQL 支持类似于 Oracle 匿名块的功能。在 PostgreSQL 中,您可以使用 PL/pgSQL 的DO语句将未存储在数据库中的 PL/pgSQL 代码作为独立代码段运行。

PL/pgSQL 是 ANSI SQL 的 PostgreSQL 扩展,具有许多与 Oracle PL/SQL 相似的元素。PostgreSQL 的DO语法使用与 Oracle 匿名块类似的代码结构:

  • • 声明性部分(可选)。
  • • 可执行文件部分(必需)。
  • • 异常处理部分(可选)。

例子:

PostgreSQL DO 简单的结构。

SET CLIENT_MIN_MESSAGES = 'debug';
-- Equivalent To Oracle SET SERVEROUTPUT ON

DO $$
BEGIN
  RAISE DEBUG USING MESSAGE := 'hello world';
END $$;
DEBUG: hello world
DO

PostgreSQL PL/pgSQL DO语句支持使用高级代码元素,如函数、游标、动态 SQL 和条件逻辑。

以下示例是从上一节中介绍的 Oracle “员工奖金” PL/SQL 匿名块示例转换而来的更复杂的 PL/pgSQL DO 代码结构:

DO $$
DECLARE
  v_sal_chk DOUBLEPRECISION;
  v_emp_work_years DOUBLEPRECISION;
  v_sql_cmd CHARACTERVARYING(2000);
  v RECORD;
BEGIN
FOR v IN
SELECT employee_id, CONCAT_WS('', first_name,' ', last_name)AS emp_name, hire_date, salary FROM employees
LOOP
    v_emp_work_years := EXTRACT (YEARFROM now())- EXTRACT (YEARFROM v.hire_date);
IF v_emp_work_years >=10AND v.salary <=6000THEN
RAISEDEBUGUSING MESSAGE := CONCAT_WS('','Consider a Salary Raise for: ',v.emp_name);
ENDIF;
ENDLOOP;
EXCEPTION
WHEN others THEN
RAISEDEBUGUSING MESSAGE := CONCAT_WS('','CODE ERR: ',SQLERRM);
END $$;

有关详细信息,请参阅 PostgreSQL 文档中的 DO。

责任编辑:武晓燕 来源: 红石PG
相关推荐

2019-08-08 16:12:33

2019-09-18 10:07:24

ExcelSQL数据库

2020-07-06 15:13:16

安卓AirDrop无线传输

2021-06-30 09:20:18

NuShell工具Linux

2019-01-03 14:39:08

Oracle甲骨文ORACLE

2021-03-10 09:54:43

RustNuShell系统

2021-10-02 10:36:00

YAML编程语言软件开发

2012-03-07 17:24:10

戴尔咨询

2011-02-28 10:38:13

Windows 8

2012-12-20 10:17:32

IT运维

2009-06-12 15:26:02

2015-08-25 09:52:36

云计算云计算产业云计算政策

2024-06-28 09:34:02

2015-07-24 16:45:48

Uber

2013-01-11 18:10:56

软件

2024-05-21 10:28:51

API设计架构

2019-09-03 08:00:00

电脑硬盘程序

2017-12-19 10:24:16

2024-07-04 11:33:33

2017-05-25 15:02:46

联宇益通SD-WAN
点赞
收藏

51CTO技术栈公众号