Oracle SQL 存储过程游标未循环或插入
Oracle SQL stored procedure cursor is not looping or inserting
我正在更新 oracle 存储过程以使用游标。目的是动态地将数据从一个 table 插入到另一个。游标用于循环并自动递增字段 v_SRCROWID 由于某种原因它是 VARCHAR2。这些 table 不是我做的,所以我只是在有限地使用 PL/SQL 的情况下尽我最大的努力。我知道序列通常是可行的方法,但这不是一种选择。在游标中,我 select max(SRCROWID) 并将其加 1 以尝试递增 SRCROWID 字段,然后我执行动态 sql 语句插入 table。问题是,它似乎没有循环或向 table 中插入任何内容。
create or replace PROCEDURE
LOOKUP_TABLE_INSERT
(
P_SOURCE_DB IN VARCHAR2
, P_SOURCE_TABLE IN VARCHAR2
, P_TARGET_DB IN VARCHAR2
, P_TARGET_TABLE IN VARCHAR2
, P_COLUMN_NAME IN VARCHAR2
) AS
l_sql_statement VARCHAR2(4000);
v_SRCROWID NUMBER(10);
CURSOR c_missingvalues
IS
SELECT MISSING_VALUES AS "PKEY_SRC_OBJECT"
, 1 as "VERSION_SEQ"
, 0 as "TIMELINE_ACTION"
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as "ROLE_TP"
FROM ECH_ETL_BATCH_ID.REF_INTERMEDIATE
WHERE COLUMN_NM = P_COLUMN_NAME --''''||P_COLUMN_NAME||''''
AND LOOKUP_TBL_NM = P_TARGET_TABLE; --''''||P_TARGET_TABLE||'''';
r_missingvalues c_missingvalues%ROWTYPE;
BEGIN
v_SRCROWID := 0;
l_sql_statement := '';
OPEN c_missingvalues;
LOOP
SELECT MAX(CAST(SRC_ROWID AS INTEGER)) INTO v_SRCROWID FROM
ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP;
FETCH c_missingvalues INTO r_missingvalues;
EXIT WHEN c_missingvalues%NOTFOUND;
SELECT 'INSERT INTO '|| P_TARGET_DB ||'.'|| P_TARGET_TABLE||'
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID,
HUB_STATE_IND, ROLE_TP) '||
'VALUES( ' ||''''|| r_missingvalues.PKEY_SRC_OBJECT ||''''||
','|| ''''|| r_missingvalues.VERSION_SEQ ||''''||
','|| ''''|| r_missingvalues.TIMELINE_ACTION ||''''||
','|| SYSDATE ||
',' || v_SRCROWID ||' + 1' ||
','|| ''''|| r_missingvalues.HUB_STATE_IND ||''''||
','|| ''''|| r_missingvalues.ROLE_TP ||''''||
');' INTO l_sql_statement FROM DUAL;
dbms_output.put_line(l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement;
EXECUTE IMMEDIATE 'COMMIT';
END LOOP;
CLOSE c_missingvalues;
COMMIT;
END;
你的动态表述很差。最好这样使用它:
l_sql_statement := 'INSERT INTO '|| P_TARGET_DB ||'.'|| P_TARGET_TABLE||'
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID,
HUB_STATE_IND, ROLE_TP)
VALUES
(:PKEY_SRC_OBJECT, :VERSION_SEQ, :TIMELINE_ACTION, :LAST_UPDATE_DATE, :SRC_ROWID,
:HUB_STATE_IND, :ROLE_TP)';
--dbms_output.put_line(l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement USING
r_missingvalues.PKEY_SRC_OBJECT,
r_missingvalues.VERSION_SEQ,
r_missingvalues.TIMELINE_ACTION,
SYSDATE,
v_SRCROWID + 1, -- or better SEQUENCE_NAME.NEXTVAL,
r_missingvalues.HUB_STATE_IND,
r_missingvalues.ROLE_TP;
COMMIT;
或者像这样更好(假设你出于任何原因不能使用序列):
CREATE OR REPLACE PROCEDURE LOOKUP_TABLE_INSERT (
P_SOURCE_DB IN VARCHAR2
, P_SOURCE_TABLE IN VARCHAR2
, P_TARGET_DB IN VARCHAR2
, P_TARGET_TABLE IN VARCHAR2
, P_COLUMN_NAME IN VARCHAR2
) AS
l_sql_statement VARCHAR2(4000);
v_SRCROWID NUMBER(10);
BEGIN
SELECT MAX(CAST(SRC_ROWID AS INTEGER))
INTO v_SRCROWID
FROM ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP;
l_sql_statement := 'INSERT INTO '|| P_TARGET_DB ||'.'|| P_TARGET_TABLE||'
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID,
HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES, 1, 0, :LAST_UPDATE_DATE, :SRC_ROWID + ROWNUM, 1, MISSING_VALUES ' -- why MISSING_VALUES twice?
||' FROM ECH_ETL_BATCH_ID.REF_INTERMEDIATE
WHERE COLUMN_NM = :P_COLUMN_NAME
AND LOOKUP_TBL_NM = :P_TARGET_TABLE';
EXECUTE IMMEDIATE l_sql_statement USING SYSDATE, v_SRCROWID, P_COLUMN_NAME, P_TARGET_TABLE;
COMMIT;
END;
我正在更新 oracle 存储过程以使用游标。目的是动态地将数据从一个 table 插入到另一个。游标用于循环并自动递增字段 v_SRCROWID 由于某种原因它是 VARCHAR2。这些 table 不是我做的,所以我只是在有限地使用 PL/SQL 的情况下尽我最大的努力。我知道序列通常是可行的方法,但这不是一种选择。在游标中,我 select max(SRCROWID) 并将其加 1 以尝试递增 SRCROWID 字段,然后我执行动态 sql 语句插入 table。问题是,它似乎没有循环或向 table 中插入任何内容。
create or replace PROCEDURE
LOOKUP_TABLE_INSERT
(
P_SOURCE_DB IN VARCHAR2
, P_SOURCE_TABLE IN VARCHAR2
, P_TARGET_DB IN VARCHAR2
, P_TARGET_TABLE IN VARCHAR2
, P_COLUMN_NAME IN VARCHAR2
) AS
l_sql_statement VARCHAR2(4000);
v_SRCROWID NUMBER(10);
CURSOR c_missingvalues
IS
SELECT MISSING_VALUES AS "PKEY_SRC_OBJECT"
, 1 as "VERSION_SEQ"
, 0 as "TIMELINE_ACTION"
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as "ROLE_TP"
FROM ECH_ETL_BATCH_ID.REF_INTERMEDIATE
WHERE COLUMN_NM = P_COLUMN_NAME --''''||P_COLUMN_NAME||''''
AND LOOKUP_TBL_NM = P_TARGET_TABLE; --''''||P_TARGET_TABLE||'''';
r_missingvalues c_missingvalues%ROWTYPE;
BEGIN
v_SRCROWID := 0;
l_sql_statement := '';
OPEN c_missingvalues;
LOOP
SELECT MAX(CAST(SRC_ROWID AS INTEGER)) INTO v_SRCROWID FROM
ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP;
FETCH c_missingvalues INTO r_missingvalues;
EXIT WHEN c_missingvalues%NOTFOUND;
SELECT 'INSERT INTO '|| P_TARGET_DB ||'.'|| P_TARGET_TABLE||'
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID,
HUB_STATE_IND, ROLE_TP) '||
'VALUES( ' ||''''|| r_missingvalues.PKEY_SRC_OBJECT ||''''||
','|| ''''|| r_missingvalues.VERSION_SEQ ||''''||
','|| ''''|| r_missingvalues.TIMELINE_ACTION ||''''||
','|| SYSDATE ||
',' || v_SRCROWID ||' + 1' ||
','|| ''''|| r_missingvalues.HUB_STATE_IND ||''''||
','|| ''''|| r_missingvalues.ROLE_TP ||''''||
');' INTO l_sql_statement FROM DUAL;
dbms_output.put_line(l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement;
EXECUTE IMMEDIATE 'COMMIT';
END LOOP;
CLOSE c_missingvalues;
COMMIT;
END;
你的动态表述很差。最好这样使用它:
l_sql_statement := 'INSERT INTO '|| P_TARGET_DB ||'.'|| P_TARGET_TABLE||'
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID,
HUB_STATE_IND, ROLE_TP)
VALUES
(:PKEY_SRC_OBJECT, :VERSION_SEQ, :TIMELINE_ACTION, :LAST_UPDATE_DATE, :SRC_ROWID,
:HUB_STATE_IND, :ROLE_TP)';
--dbms_output.put_line(l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement USING
r_missingvalues.PKEY_SRC_OBJECT,
r_missingvalues.VERSION_SEQ,
r_missingvalues.TIMELINE_ACTION,
SYSDATE,
v_SRCROWID + 1, -- or better SEQUENCE_NAME.NEXTVAL,
r_missingvalues.HUB_STATE_IND,
r_missingvalues.ROLE_TP;
COMMIT;
或者像这样更好(假设你出于任何原因不能使用序列):
CREATE OR REPLACE PROCEDURE LOOKUP_TABLE_INSERT (
P_SOURCE_DB IN VARCHAR2
, P_SOURCE_TABLE IN VARCHAR2
, P_TARGET_DB IN VARCHAR2
, P_TARGET_TABLE IN VARCHAR2
, P_COLUMN_NAME IN VARCHAR2
) AS
l_sql_statement VARCHAR2(4000);
v_SRCROWID NUMBER(10);
BEGIN
SELECT MAX(CAST(SRC_ROWID AS INTEGER))
INTO v_SRCROWID
FROM ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP;
l_sql_statement := 'INSERT INTO '|| P_TARGET_DB ||'.'|| P_TARGET_TABLE||'
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID,
HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES, 1, 0, :LAST_UPDATE_DATE, :SRC_ROWID + ROWNUM, 1, MISSING_VALUES ' -- why MISSING_VALUES twice?
||' FROM ECH_ETL_BATCH_ID.REF_INTERMEDIATE
WHERE COLUMN_NM = :P_COLUMN_NAME
AND LOOKUP_TBL_NM = :P_TARGET_TABLE';
EXECUTE IMMEDIATE l_sql_statement USING SYSDATE, v_SRCROWID, P_COLUMN_NAME, P_TARGET_TABLE;
COMMIT;
END;