无法在 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;
/
我想使用 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;
/