【发布时间】:2014-04-04 14:18:54
【问题描述】:
我在我的过程中发现“ORA-01422:精确提取返回的行数超过请求的行数”错误,我搜索了它的解决方案并得到一个想法,要解决此类问题,我们必须使用游标或集合在我们的程序中。
我在我的程序中使用光标,逻辑/技术与正常程序有点不同。所以,我很困惑如何更改程序中的逻辑,以便我可以使用集合、记录或批量集合?
谢谢,这是我的程序。
create or replace PROCEDURE DB_TZ_PROC AUTHID CURRENT_USER IS
V_DBNAME VARCHAR2(20);
V_INSTANCE VARCHAR2(10);
V_TIME VARCHAR2(20);
V_DB_TIME TIMESTAMP(6);
V_SERVER_TZ VARCHAR2(10);
V_RPT_SER_TIME VARCHAR2(50);
V_SERVER_DATE DATE;
V_SESSION_TZ VARCHAR2(30);
V_DBZONE VARCHAR2(10);
V_DATE DATE;
V_ERRORSTRING varchar2(4000);
V_EXEC_STRING VARCHAR2(6000);
TABLE_NAME VARCHAR2(30):='TIMEZONE_DIFF';
INN_EXCEPTION VARCHAR2(30):='INNER_EXCEPTION';
OUT_EXCEPTION VARCHAR2(30):='OUTER_EXCEPTION';
CURSOR DBNAME_CUR IS SELECT DBNAME FROM CRMODDEV.FHM_DB_D WHERE (podname ='xyz');
BEGIN
OPEN DBNAME_CUR;
LOOP
FETCH DBNAME_CUR INTO V_DBNAME;
EXIT WHEN DBNAME_CUR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('V_DBNAME1 :'||V_DBNAME);
BEGIN
V_EXEC_STRING:='select instance_name,
startup_time,
database_default_time,
server_tz,
rpt_server_time,
session_tz,
dbtime_zone,
server_current_date,
timezone_date
from (select a.inst_id,
upper(b.instance_name) instance_name,
to_char(b.startup_time, ''YYYY-MM-DD HH24:MI'') startup_time,
SYSTIMESTAMP database_default_time,
substr(to_char(SYSTIMESTAMP), 30) server_tz,
CURRENT_TIMESTAMP rpt_server_time,
substr(to_char(CURRENT_TIMESTAMP), 30) session_tz,
dbtimezone dbtime_zone,
to_date(to_char(max(sample_time),''YYYY-MM-DD HH24:MI:SS''),''YYYY-MM-DD HH24:MI:SS'') server_current_date,
SYSTIMESTAMP AT TIME ZONE ''UTC'' timezone_date
from gv$active_session_history@'||V_DBNAME||' a, gv$instance@'||V_DBNAME||' b
where a.inst_id = b.inst_id
group by a.inst_id,
upper(b.instance_name),
to_char(b.startup_time, ''YYYY-MM-DD HH24:MI''),
dbtimezone)
DBMS_OUTPUT.PUT_LINE('V_DBNAME2 :'||V_DBNAME);
EXECUTE IMMEDIATE V_EXEC_STRING INTO V_INSTANCE,V_TIME,V_DB_TIME,V_SERVER_TZ,V_RPT_SER_TIME,V_SESSION_TZ,V_DBZONE,V_SERVER_DATE,V_DATE;
DBMS_OUTPUT.PUT_LINE('V_INSTANCE:'||V_INSTANCE);
DBMS_OUTPUT.PUT_LINE('V_SERVER_TZ:'||V_SERVER_TZ);
DBMS_OUTPUT.PUT_LINE('V_DBZONE:'||V_DBZONE);
INSERT INTO TIMEZONE_DIFF(DB_INSTANCE,STARTUP_TIME,DATABASE_DEFAULT_TIME,SERVER_TZ,RPT_SERVER_TIME,SESSION_TZ,DBZONE,TIMEZONE_DATE,COLLECTION_DATE)
VALUES (V_INSTANCE,V_TIME,V_DB_TIME,V_SERVER_TZ,V_RPT_SER_TIME,V_SESSION_TZ,V_DBZONE,V_DATE,TRUNC(SYSDATE));
COMMIT;
DBMS_OUTPUT.PUT_LINE('V_DBNAME3 :'||V_DBNAME);
UPDATE TIMEZONE_DIFF SET COLLECTION_DATE=TRUNC(COLLECTION_DATE);
COMMIT;
-- INNER EXCEPTION
EXCEPTION
WHEN OTHERS THEN
V_ERRORSTRING:= 'INSERT INTO CRMODDEV.TIMEZONE_DIFF_LOG VALUES ('''||V_DBNAME||''','''||TABLE_NAME||''','''||SQLCODE||''','''||SQLERRM||''',SYSDATE,'''||INN_EXCEPTION||''')';
EXECUTE IMMEDIATE v_errorstring;
COMMIT;
DBMS_OUTPUT.PUT_LINE('DBMS_UTILITY.FORMAT_ERROR_BACKTRACE FOR INNER BLOCK:'||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
END LOOP;
CLOSE DBNAME_CUR;
-- OUTER EXCEPTION
EXCEPTION
WHEN OTHERS THEN
V_ERRORSTRING:= 'INSERT INTO CRMODDEV.TIMEZONE_DIFF_LOG VALUES ('''||V_DBNAME||''','''||TABLE_NAME||''','''||SQLCODE||''','''||SQLERRM||''',SYSDATE,'''||OUT_EXCEPTION||''')';
EXECUTE IMMEDIATE v_errorstring;
COMMIT;
DBMS_OUTPUT.PUT_LINE('DBMS_UTILITY.FORMAT_ERROR_BACKTRACE FOR OUTER BLOCK:'||DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END DB_TZ_PROC;
【问题讨论】: