无法在oracle中使用游标在表中插入记录

无法在oracle中使用游标在表中插入记录,oracle,stored-procedures,plsql,cursor,Oracle,Stored Procedures,Plsql,Cursor,我想使用光标将记录插入表中。下面是对相同问题的查询 CREATE OR REPLACE PROCEDURE FIBER_TRANSM_VALID_DATA AS BEGIN DECLARE SPANID NVARCHAR2(50); MZONENAME NVARCHAR2(50); CURSOR CR_SPAN_VALID_DATA IS SELECT RJ_SPAN_ID, RJ_MAINTENANCE_ZONE_NAME FROM APP_FTTX.tran

我想使用
光标
将记录插入表中。下面是对相同问题的查询

CREATE OR REPLACE PROCEDURE FIBER_TRANSM_VALID_DATA 
AS 

BEGIN

DECLARE

SPANID NVARCHAR2(50);
MZONENAME NVARCHAR2(50);


CURSOR CR_SPAN_VALID_DATA IS

 SELECT RJ_SPAN_ID, RJ_MAINTENANCE_ZONE_NAME
        FROM APP_FTTX.transmedia@SAT
        WHERE  LENGTH(RJ_SPAN_ID) = 21
       AND INVENTORY_STATUS_CODE = 'IPL'
       AND REGEXP_LIKE(rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
       AND RJ_MAINTENANCE_ZONE_CODE IN ('INMUNVMB01')
       AND ROWNUM < 11;  


BEGIN      
    OPEN CR_SPAN_VALID_DATA;
    LOOP    
    FETCH CR_SPAN_VALID_DATA INTO SPANID, MZONENAME;
    EXIT WHEN CR_SPAN_VALID_DATA%NOTFOUND;    

    IF SPANID > 0
    THEN
        BEGIN                              
            INSERT INTO TBL_FIBER_VALID_TRANS_DATA (RJ_SPAN_ID, RJ_MAINTENANCE_ZONE_NAME)
            VALUES (SPANID, MZONENAME);           

        END;
       END IF; 
          COMMIT;

       END LOOP;  
  CLOSE CR_SPAN_VALID_DATA;  

END;
END FIBER_TRANSM_VALID_DATA;

整个PL/SQL代码可以用一个简单的
INSERT-in..SELECT编写。无需循环遍历游标中的每条记录,只需在纯SQL中执行即可:

INSERT INTO TBL_FIBER_VALID_TRANS_DATA 
  (SPAN_ID, MAINTENANCE_ZONE_NAME)
SELECT RJ_SPAN_ID, RJ_MAINTENANCE_ZONE_NAME
FROM APP_FTTX.transmedia@SAT
WHERE  LENGTH(RJ_SPAN_ID) = 21
AND INVENTORY_STATUS_CODE = 'IPL'
AND REGEXP_LIKE(rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
AND RJ_MAINTENANCE_ZONE_CODE IN ('INMUNVMB01')
AND ROWNUM < 11
AND SPAN_ID > 0; --> This is the check you are using in your PL/SQL code
插入TBL\u光纤有效传输数据
(SPAN\u ID、维护区\名称)
选择RJ_跨度_ID、RJ_维护_区域_名称
来自APP_FTTX。transmedia@SAT
式中,长度(RJ_SPAN_ID)=21
库存状态代码='IPL'
和REGEXP_LIKE(rj_span_id,'SP(N | Q | R | S)。*(BU | MP)$)
和RJ_维护_区域_代码('INMUNVMB01')
和ROWNUM<11
和SPAN_ID>0;-->这是您在PL/SQL代码中使用的检查
和ROWNUM<11


我希望您知道,
ROWNUM
只会给您随机获取的行,它不会以任何特定的顺序出现,除非您特别提到
order BY
,然后在上面应用ROWNUM。在代码中,您将获得
10
随机行。要了解更多信息,请参阅。

您的整个PL/SQL代码可以用一个简单的
插入..选择
。无需循环遍历游标中的每条记录,只需在纯SQL中执行即可:

INSERT INTO TBL_FIBER_VALID_TRANS_DATA 
  (SPAN_ID, MAINTENANCE_ZONE_NAME)
SELECT RJ_SPAN_ID, RJ_MAINTENANCE_ZONE_NAME
FROM APP_FTTX.transmedia@SAT
WHERE  LENGTH(RJ_SPAN_ID) = 21
AND INVENTORY_STATUS_CODE = 'IPL'
AND REGEXP_LIKE(rj_span_id, 'SP(N|Q|R|S).*_(BU|MP)$')
AND RJ_MAINTENANCE_ZONE_CODE IN ('INMUNVMB01')
AND ROWNUM < 11
AND SPAN_ID > 0; --> This is the check you are using in your PL/SQL code
插入TBL\u光纤有效传输数据
(SPAN\u ID、维护区\名称)
选择RJ_跨度_ID、RJ_维护_区域_名称
来自APP_FTTX。transmedia@SAT
式中,长度(RJ_SPAN_ID)=21
库存状态代码='IPL'
和REGEXP_LIKE(rj_span_id,'SP(N | Q | R | S)。*(BU | MP)$)
和RJ_维护_区域_代码('INMUNVMB01')
和ROWNUM<11
和SPAN_ID>0;-->这是您在PL/SQL代码中使用的检查
和ROWNUM<11


我希望您知道,
ROWNUM
只会给您随机获取的行,它不会以任何特定的顺序出现,除非您特别提到
order BY
,然后在上面应用ROWNUM。在代码中,您将获得
10
随机行。要了解更多信息,请参阅。

如果必须是游标循环,请参阅另一种方法-游标
用于
循环。它更易于编写和维护,因为Oracle为您完成了大部分工作,即您不必显式声明游标和游标变量、打开它、从中提取、注意何时退出循环、关闭游标。所有那些肮脏的工作都是为你做的

您需要担心的是,您编写的
select
实际上返回了一些行,因为我看到了您编写的注释-尽管过程已编译,但它没有插入任何行。由于我们没有你的数据,我们无法帮助你

接下来(假设表和列确实存在):

还有一些注意事项:不要在循环中提交,因为它会导致问题(例如快照太旧错误)。考虑将它完全移出程序,并让调用方决定是否提交。 你真的执行了这个程序吗?您确实创建了它,但如果您从未调用过它,这可能就是您没有看到任何行被插入的原因。因此:

begin
  fiber_transm_valid_data ;
end;
/

如果必须是游标循环,请参阅另一种方法-游标
FOR
循环。它更易于编写和维护,因为Oracle为您完成了大部分工作,即您不必显式声明游标和游标变量、打开它、从中提取、注意何时退出循环、关闭游标。所有那些肮脏的工作都是为你做的

您需要担心的是,您编写的
select
实际上返回了一些行,因为我看到了您编写的注释-尽管过程已编译,但它没有插入任何行。由于我们没有你的数据,我们无法帮助你

接下来(假设表和列确实存在):

还有一些注意事项:不要在循环中提交,因为它会导致问题(例如快照太旧错误)。考虑将它完全移出程序,并让调用方决定是否提交。 你真的执行了这个程序吗?您确实创建了它,但如果您从未调用过它,这可能就是您没有看到任何行被插入的原因。因此:

begin
  fiber_transm_valid_data ;
end;
/

当SQL>desc TBL\u FIBER\u VALID\u TRANS\u DATA发出时,您会得到什么。@BarbarosÖzhan:表的结构,它由几个其他列组成。这意味着表是否包含名为
RJ\u MAINTENANCE\u ZONE\u NAME
的列,您确定表中存在此列吗?@BarbarosÖzhan让我再次检查并发布表结构here@BarbarosÖzhan:很抱歉,这是我的列搞错了。当SQL>desc TBL_FIBER_VALID_TRANS_DATA发出时,您得到了什么。@BarbarosÖzhan:表的结构,它由其他几列组成。这意味着表中是否包含名为
RJ_MAINTENANCE_ZONE_NAME
的列,您确定表中存在此列吗?@BarbarosÖzhan让我再次检查并发布表结构here@BarbarosÖzhan:很抱歉我的专栏搞错了谢谢lalit的回答,但我想用光标来做,有可能吗。?我快做完了。我猜是因为当我删除ROWNUM时,你的回答方式花费了太多时间part@nkbSQL总是比PL/SQL快。如果您仍然希望使用游标在PL/SQL中逐行执行a.k.a.slow by slow,请使用
FORALL
语句查看
BULK COLLECT
。关于
ROWNUM
,请参阅我提供的链接。感谢lalit的回答,但我想用游标来完成,是否可能。?我快做完了。我猜是因为当我删除ROWNUM时,你的回答方式花费了太多时间part@nkbSQL总是比PL/SQL快。如果您仍然希望使用游标在PL/SQL中逐行执行a.k.a.slow by slow,请使用
FORALL
语句查看
BULK COLLECT
。关于
ROWNUM
,请参阅我提供的链接。感谢littlefoot的回答。我一定会尝试你的代码,并测试它是否正常工作