ORA 22905 無法從非巢狀項訪問行 之解決

2021-04-21 07:32:04 字數 3027 閱讀 4726

今天筆者在幫同事寫乙個格式化日期函式的過程中,在呼叫管道(pipeline) 實現的函式時,遇到了乙個oracle異常: ora-22905:無法從非巢狀項訪問行.

注:(有關巢狀表參見:http://blog.csdn.net/simonezhlx/archive/2008/10/28/3167343.aspx)

具體情況:為了實現日期字串的格式化,需要對傳入的字串進行分拆.然後視情況補0後再連線成乙個字串.

為了實現該應用,建立了乙個型別,兩個函式.如下:

--建立型別

create or replace type type_split as table of varchar2(50);

--建立通用split函式

create or replace function commonsplit(sourcestr in varchar2,sepmark in varchar2)

return type_split pipelined is

l_idx  integer;

v_list  varchar2(500) := sourcestr;

begin

loop

l_idx := instr(v_list,sepmark);

if l_idx > 0 then

pipe row(substr(v_list,1,l_idx-1));

v_list := substr(v_list,l_idx+length(sepmark));

else

pipe row(v_list);

exit;

end if;

end loop;

return;

end commonsplit;

--建立日期格式化函式

create or replace function formatdatestr(sourcedate in varchar2)

return varchar2 is

sreturnvalue varchar2(8);

sepmark varchar2(1):='-';

stemp varchar2(20);

cursor cu1(p1 varchar2,p2 varchar2) 

is select * from table(commonsplit(p1,p2)) ;

begin

if length(sourcedate) <= 8 then

--八位或不滿足條件的輸入日期

sreturnvalue := sourcedate;

else

if instr( sourcedate,sepmark ) > 0 then

open cu1(sourcedate,sepmark);    

loop

fetch cu1 into stemp;

exit when cu1%notfound;

if length(stemp) = 1 then --補0

stemp:= '0' || stemp;

end if;

sreturnvalue:= sreturnvalue || stemp;

end loop;

close cu1;

end if;

end if;

return(sreturnvalue);

end formatdatestr;

但編寫完成在測試時發現在執行到紅色字型也就是執行游標查詢時會有異常出現(ora-22905:無法從非巢狀項訪問行).

嘗試多次,均無果,最後只得變換方式,將游標改為無參,靠生成動態sql來完成游標查詢.結果問題解決.如下:

create or replace function formatdatestr(sourcedate in varchar2)

return varchar2 is

sreturnvalue varchar2(8);

sepmark varchar2(1):='-';

stemp varchar2(20);

v_sql_select varchar2(400);

type v_cursor is ref cursor;

cu1 v_cursor;

--   cursor cu1(p1 varchar2,p2 varchar2)

-- is select * from table(commonsplit(p1,p2)) ;

-- is select * from table(commonsplit('' || p1 || '','' || p2 || ''));

begin

if length(sourcedate) <= 8 then

--八位或不滿足條件的輸入日期

sreturnvalue := sourcedate;

else

if instr( sourcedate,sepmark ) > 0 then

--open cu1(sourcedate,sepmark);   

v_sql_select:='select * from table(commonsplit(''' || sourcedate

|| ''',''' || sepmark || '''))';    

open cu1 for v_sql_select;

loop

fetch cu1 into stemp;

exit when cu1%notfound;

if length(stemp) = 1 then --補0

stemp:= '0' || stemp;

end if;

sreturnvalue:= sreturnvalue || stemp;

end loop;

close cu1;

end if;

end if;

return(sreturnvalue);

end formatdatestr;

紅色為修改後內容,但是始終不知道為什麼使用引數方式會有問題.如有知者告之,筆者甚感之至.

Oracle TNS無法解析ORA 12154報錯

在伺服器配置好python開發環境,進行資料庫連線測試時發現,程式執行報錯 cx oracle.databaseerror ora 12154 tns 無法解析指定的連線識別符號 分析 在我本機電腦測試資料庫連線正常,伺服器有問題,伺服器的資料庫使用正常,任務計畫也正常執行 進行tnsping or...

ORA 04031 無法分配 共享記憶體

今天現場專案oracle系統定時器插入資料報錯 ora 04031 無法分配 3936 位元組的共享記憶體 shared pool truncate table jxd7 pub rtdb.sga heap 1,0 kglsim object batch 第一種 治標不治本 alter system...

ora 01940 無法刪除當前連線使用者

英文提示如下 ora 01940 cannot drop a user that is currently connected 產生原因 由於當前使用者正在連線到資料庫,所以無法刪除。解決辦法 1.檢視此使用者的會話過程 sql select sid,serial from v session wh...