Oracle 存过 与Postgresql 的存过的差别

一、Oracle 存储过程

CREATE OR REPLACE PROCEDURE display_employees_with_cursor AS  
    -- 声明游标  
    CURSOR emp_cursor IS  
        SELECT employee_id, first_name, salary FROM employees;  
  
    -- 声明变量来存储从游标中检索的数据  
    v_employee_id   employees.employee_id%TYPE;  
    v_first_name    employees.first_name%TYPE;  
    v_salary        employees.salary%TYPE;  
BEGIN  
    -- 打开游标  
    OPEN emp_cursor;  
  
    -- 循环遍历游标中的每一行  
    LOOP  
        -- 从游标中检索数据  
        FETCH emp_cursor INTO v_employee_id, v_first_name, v_salary;  
  
        -- 退出循环的条件:如果没有更多的数据可检索(即游标已到达末尾)  
        EXIT WHEN emp_cursor%NOTFOUND;  
  
        -- 在这里处理每一行的数据。例如,我们可以简单地将它们打印到控制台(注意:在Oracle PL/SQL中,通常不会直接打印到控制台,但这里只是作为示例)  
        DBMS_OUTPUT.PUT_LINE('Employee ID: ' || v_employee_id || ', Name: ' || v_first_name || ', Salary: ' || TO_CHAR(v_salary));  
    END LOOP;  
  
    -- 关闭游标  
    CLOSE emp_cursor;  
EXCEPTION  
    WHEN OTHERS THEN  
        -- 异常处理:如果发生任何错误,关闭游标并重新抛出异常  
        IF emp_cursor%ISOPEN THEN  
            CLOSE emp_cursor;  
        END IF;  
        RAISE;  
END display_employees_with_cursor;

Oracle的变量申明弱限制,Pgsql 需要强制先申明后使用。

二、Pgsql 存过过程

CREATE OR REPLACE FUNCTION process_with_cursor()  
RETURNS void AS 
$$
  
DECLARE  
    row_record RECORD;  
    my_cursor CURSOR FOR SELECT * FROM your_table_name; -- 替换 your_table_name 为你的表名  
BEGIN  
    -- 打开游标  
    OPEN my_cursor;  
  
    -- 循环遍历游标中的每一行  
    LOOP  
        -- 从游标中获取一行数据  
        FETCH my_cursor INTO row_record;  
  
        -- 退出循环的条件:如果没有更多的数据可检索(即游标已到达末尾)  
        EXIT WHEN NOT FOUND;  
  
        -- 在这里处理每一行的数据。例如,我们可以将数据输出到日志中  
        RAISE NOTICE 'Processing row: ID = %, Name = %', row_record.id, row_record.name; -- 假设表有 id 和 name 列  
    END LOOP;  
  
    -- 关闭游标  
    CLOSE my_cursor;  
EXCEPTION  
    WHEN OTHERS THEN  
        -- 如果发生异常,确保游标被关闭  
        IF my_cursor%ISOPEN THEN  
            CLOSE my_cursor;  
        END IF;  
        -- 重新抛出异常  
        RAISE;  
END;  
 
$$
 LANGUAGE plpgsql;

调用这个函数的 SQL 语句如下:

SELECT process_with_cursor();

但是请注意,这个函数不会返回任何结果集给调用者,它只是将处理过程中的信息输出到 PostgreSQL 的日志中。

如果你想要使用 PostgreSQL 16 引入的过程(Procedures),过程与函数类似,但过程不返回任何值(即它们没有返回类型)。以下是一个使用过程的样例:

sql

复制代码

CREATE OR REPLACE PROCEDURE process_with_cursor_procedure()  
LANGUAGE plpgsql AS 
$$
  
DECLARE  
    row_record RECORD;  
    my_cursor CURSOR FOR SELECT * FROM your_table_name; -- 替换 your_table_name 为你的表名  
BEGIN  
    -- ... 与上面的函数相同的游标处理逻辑 ...  
END;  
 
$$
;

调用这个过程的 SQL 语句是:

CALL process_with_cursor_procedure();

三、差异

Oracle 11g的存储过程(Stored Procedure)和PostgreSQL 16的存储过程(在PostgreSQL中通常称为函数或过程,但从PostgreSQL 11开始正式引入了存储过程的概念)之间存在一些异同点。以下是它们之间的一些主要区别:

相似点:

1、封装逻辑:两者都允许将复杂的SQL逻辑封装在可重用的单元中,以便在多个地方调用。

2、参数化:存储过程和函数都可以接受参数,这使得它们更加灵活和可重用。

3、性能优化:由于存储过程和函数是预编译的,因此在多次调用时可以提供更好的性能。

4、安全性:它们都可以用来隐藏数据库表结构或复杂性,从而提供某种程度的安全性。

5、错误处理:两者都支持异常处理,可以在存储过程或函数内部捕获和处理错误。

不同点:

1、语法差异:Oracle和PostgreSQL使用不同的SQL方言,因此在编写存储过程或函数时会有语法差异。

Oracle使用PL/SQL作为存储过程和函数的编程语言。

PostgreSQL使用PL/pgSQL(或其他支持的过程语言)作为函数的编程语言,而从PostgreSQL 11开始,也支持使用SQL语言编写存储过程。

2、返回类型:

在Oracle中,存储过程通常不返回值(或结果集),但可以通过输出参数返回数据。函数可以返回一个值或结果集。

在PostgreSQL中,函数可以返回一个值、一个表或一组行(即结果集)。从PostgreSQL 11开始引入的存储过程也不直接返回值,但可以通过输出参数或OUT参数返回数据。

3、调用方式:

在Oracle中,存储过程通常使用EXECUTE命令或直接在PL/SQL块中调用。

在PostgreSQL中,函数可以使用SELECT语句调用(如果它们返回结果集),而存储过程可以使用CALL语句调用。

4、错误处理:虽然两者都支持异常处理,但具体的语法和用法可能有所不同。

5、工具和生态系统:Oracle和PostgreSQL有不同的工具和生态系统,这可能会影响存储过程和函数的开发、部署和管理。

6、移植性:由于语法和功能的差异,Oracle的存储过程可能无法直接移植到PostgreSQL,而需要进行一些修改。同样,PostgreSQL的函数或存储过程也可能需要进行修改才能在Oracle上运行。

总的来说,虽然Oracle 11g的存储过程和PostgreSQL 16的存储过程(或函数)在概念上相似,但在具体实现和使用上存在一些差异。

相关推荐
Python私教1 小时前
model中能定义字段声明不存储到数据库吗
数据库·oracle
BestandW1shEs4 小时前
谈谈Mysql的常见基础问题
数据库·mysql
重生之Java开发工程师4 小时前
MySQL中的CAST类型转换函数
数据库·sql·mysql
教练、我想打篮球4 小时前
66 mysql 的 表自增长锁
数据库·mysql
Ljw...4 小时前
表的操作(MySQL)
数据库·mysql·表的操作
哥谭居民00014 小时前
MySQL的权限管理机制--授权表
数据库
wqq_9922502774 小时前
ssm旅游推荐系统的设计与开发
数据库·旅游
难以触及的高度5 小时前
mysql中between and怎么用
数据库·mysql
Jacky(易小天)5 小时前
MongoDB比较查询操作符中英对照表及实例详解
数据库·mongodb·typescript·比较操作符