【问题标题】:Iterating and Dynamically Changing Elements of Type in PostgreSQL在 PostgreSQL 中迭代和动态改变类型的元素
【发布时间】:2016-11-21 09:44:14
【问题描述】:

最近有人要求我将数据库从 Oracle 迁移到 Postgres(在这件事上我没有真正的选择)。使用 ora2pg 工具,我已经成功迁移了大部分 DDL,但真正令人头疼的是,当我接触到一些 PL/SQL 代码时。

过于简单化了,这里有一些代码代表了我的大部分问题(类似的问题出现在代码的多个部分)。

sql_statement := 'SELECT * FROM TABLE_1';

OPEN ref_cursor FOR sql_statement;
FETCH ref_cursor BULK COLLECT INTO list_a_aux;

WHILE list_a_aux.COUNT <> 0
LOOP
    FOR n in list_a_aux.FIRST..list_a_aux.LAST
    LOOP
        IF list_a_aux(n).id = 0 THEN
            list_a.EXTEND;
            list_a(list_a.COUNT).id = 1;
            list_a_aux.DELETE(n);
        ELSE
            -- More Application Logic
        END IF;
    END LOOP;
END LOOP;

list_a 和 list_a_aux 都被初始化为:

list_a      list_a:= list_a();
list_a_aux  list_a:= list_a();

其中 list_a 是一个声明为的类型:

TYPE list_a IS TABLE OF TABLE_2;

我遇到的第一个问题是“BULK COLLECT”声明。我搜索了一些邮件列表,我被指向HERE。 我理解了这个解决方案,它看起来很简单,但后来我更深入地研究了代码,我无法弄清楚如何将它与代码的其余部分集成。我尝试搜索与此代码中存在的问题类似的问题,并找到了许多单个问题的解决方案(12 等),但似乎没有一个适合这个特定问题(甚至组合时!)。

关于如何迁移这段 PL/SQL 的任何想法?

【问题讨论】:

    标签: sql postgresql plpgsql database-migration ora2pg


    【解决方案1】:

    是的,PostgreSQL 中没有BULK COLLECT;你以不同的方式(也许更容易)做事。

    正如您所发现的,您可以像这样遍历查询结果:

    FOR rec_var IN SELECT ... LOOP
       <statements>
    END LOOP;
    

    如果你需要对象的集合,你可以使用数组——在你的例子中你可以使用

    DECLARE
       list_a table_2[] := ARRAY[]::table_2[];
    

    声明一个数组并将其初始化为一个空数组。有大量的array functions and operators 来操纵它们。您只需通过分配新的下标或使用array_append() 来扩展它们。没有删除某个索引处的元素的功能,但您可以通过连接元素前后的切片来创建新数组,或者更改逻辑以使用 NULL 删除元素。

    但是,您通常可以编写代码,这样您就不需要使用对象集合了。您可以使用表函数(Oracle 中的 PIPELINED 函数)一次传递一个结果。当然,这并不总是可行的,如果您的目标是迁移现有代码,则可能需要进行大量重写。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多