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

Not able to insert the records in table using cursor in oracle

我想使用 cursor 将记录插入 table。所以下面是相同的查询。

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;

但我收到错误消息

Error(36,13): PL/SQL: SQL Statement ignored Error(36,65): PL/SQL: ORA-00904: "RJ_MAINTENANCE_ZONE_NAME": invalid identifier

更新

table结构如下

SPAN_ID                       NVARCHAR2(50)  
MAINTENANCE_ZONE_NAME         NVARCHAR2(50)  
MAINTENANCE_ZONE_CODE         NVARCHAR2(50)  
R4G_STATE_NAME                NVARCHAR2(50)  
STATE_NAME                    NVARCHAR2(50)  
NETWORK_CATEGORY              NVARCHAR2(100) 
NETWORK_TYPE                  NVARCHAR2(100) 
CONSTRUCTION_METHODOLOGY      NVARCHAR2(50)  
INVENTORY_STATUS_CODE         NVARCHAR2(20)  
OWNERSHIP_TYPE_CODE           NVARCHAR2(20)  
ROUTE_NAME                    NVARCHAR2(100) 
INTRACITY_LINK_ID             NVARCHAR2(100) 
CALCULATED_LENGTH             NUMBER(38,8)   
LAST_UPDATED_BY               NVARCHAR2(100) 
LAST_UPDATED_DATE             DATE 

您的整个 PL/SQL 代码可以写成一个简单的 INSERT INTO..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

AND ROWNUM < 11

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

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

您只需要担心 select 您实际上写了 returns 一些行,因为我看到您写的评论 - 尽管程序已编译,但它没有插入任何行.由于我们没有您的数据,因此我们无能为力。

给你(假设表和列确实存在):

create or replace procedure fiber_transm_valid_data as 
begin
  for cur_r in (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')
               )
  loop               
    if cur_r.rj_span_id > '0' then
       insert into tbl_fiber_valid_trans_data 
         (span_id, maintenance_zone_name)
       values (cur_r.rj_span_id, cur_r.rj_maintenance_zone_name);
    end if;
  end loop;  
end fiber_transm_valid_data;

一些注意事项:不要在循环中 COMMIT,因为它会导致问题(例如 snapshot too old 错误)。考虑将其完全移出过程,让调用者决定是否提交。

你真的执行程序了吗?您确实创建了它,但是 - 如果您从未调用过它,这可能是您看不到任何行被插入的原因。所以:

begin
  fiber_transm_valid_data ;
end;
/