【问题标题】:PLSQL : Insert Result from Cursor into one column of plsql tablePLSQL:将光标的结果插入 plsql 表的一列
【发布时间】:2019-03-20 07:52:34
【问题描述】:

以下是我创建表对象的代码:

TYPE TempObjectsTable IS TABLE OF t_temp_objects%ROWTYPE
      INDEX BY BINARY_INTEGER;

nt_scb_temp_objects TempObjectsTable;

t_temp_objects 定义了以下列:

Name           Null? Type          
-------------- ----- ------------- 
INVC_REF             NUMBER        
ORDERS               NUMBER        
ORDER_POS_TYPE       NUMBER        
RULE_CONDITION       VARCHAR2(500) 
CHARGE               NUMBER        
CURRENCY             VARCHAR2(10)  
TXN_DT               DATE  

现在,我有一个光标,它返回一个订单列表,基本上是数字。

CURSOR c_orders_frm_grp IS 
select a.ordr_id from sa_order a 
WHERE a.invc_ref is NULL

我正在尝试使用批量收集将这些添加到上面创建的nt_scb_temp_objects 的 plsql 表中。但我现在希望nt_scb_temp_objects 的其余列填充为null,因为我将在接下来的步骤中填充这些列。

目前这是我正在尝试的。

IF c_orders_frm_grp %ISOPEN THEN
         CLOSE c_orders_frm_grp ;
    END IF;
    OPEN c_orders_frm_grp;

            FETCH c_orders_frm_grp BULK COLLECT INTO nt_scb_temp_objects.orders;             

     CLOSE   c_orders_frm_grp;

这是我得到的错误:Error(44,74): PLS-00302: component 'ORDERS' must be declared

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    您不希望 CURSOROPEN..FETCH 构造。只需运行SELECT BULK COLLECT INTO 那个集合。

    DECLARE
    TYPE TempObjectsTable IS TABLE OF t_temp_objects%ROWTYPE
          INDEX BY BINARY_INTEGER;
    nt_scb_temp_objects TempObjectsTable;
    BEGIN
    select a.ordr_id as ORDERS,
        null as INVC_REF,
        null as ORDER_POS_TYPE,
        null as RULE_CONDITION,
        null as CHARGE,
        null as CURRENCY,
        null as TXN_DT
      BULK COLLECT INTO nt_scb_temp_objects from sa_order a
    WHERE a.invc_ref is NULL ;             
    END;
    /
    

    DEMO

    【讨论】:

    • 是的。 Works,Kaushik,出于好奇,为什么要避免使用该游标构造?会影响性能吗?
    • @mastershefi : 游标在某些情况下可能有用,但在这里用处不大,因为一个简单的 SQL 就可以实现您想要的。
    【解决方案2】:

    为什么不使用INSERT INTO ... SELECT,而只指定您现在要填充的单列:

    INSERT INTO TempObjectsTable(ORDERS)
    SELECT ordr_id
    FROM sa_order
    WHERE invc_ref IS NULL;
    

    一般而言,您应该避免使用游标,因为 SQL 中的大多数常规数据库操作都是基于集合的。

    注意:如果临时表 TempObjectsTable 尚不存在,则必须创建它。

    【讨论】:

    • 我可以在 plsql 表上使用这样的命令吗?我刚试了一下,它说'表或视图不存在'
    • @mastershefi 我的回答假设临时表已经存在。如果没有,则先创建它。
    • 所以我正在使用的当前流程就是您的建议。我有一个 GTT ,我用插入命令填充。但是由于订单量大,以及其他列的表的重复更新,运行查询所需的时间很多。因此,我正在尝试转向收藏。希望我可以使用 Bulk collect 和 Bulk insert 来提高效率。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-15
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多