Oracle PLSQL:varchar变量无任何原因变为null
在尝试将一些pgpl/SQL迁移到psql oracle函数时,我发现了一个无法解释的奇怪行为 以下是我的功能:Oracle PLSQL:varchar变量无任何原因变为null,oracle,plsql,Oracle,Plsql,在尝试将一些pgpl/SQL迁移到psql oracle函数时,我发现了一个无法解释的奇怪行为 以下是我的功能: CREATE OR REPLACE FUNCTION small_distinct( tableName IN varchar, cols IN COL_ARRAY, whereCond IN varchar ) RETURN varchar IS nbcols PLS_INTEGER; currentcolnumber PLS_INTEGER
CREATE OR REPLACE FUNCTION small_distinct(
tableName IN varchar,
cols IN COL_ARRAY,
whereCond IN varchar
)
RETURN varchar
IS
nbcols PLS_INTEGER;
currentcolnumber PLS_INTEGER;
currentcol varchar(100);
firstcol varchar(100);
sqlpart varchar(4000);
firstquery_str VARCHAR2(4000);
query_str VARCHAR2(4000);
big_query_str VARCHAR2(10000);
firstresult varchar(100);
opt SYS_REFCURSOR;
BEGIN
firstcol:= cols(1);
sqlpart := firstcol;
nbcols := cols.COUNT;
currentcolnumber := 2;
big_query_str := 'SELECT * from ( SELECT '|| sqlpart ||' FROM '||tableName||' WHERE ' || whereCond|| ' ORDER BY '|| firstcol || ') WHERE ROWNUM = 1';
while currentcolnumber <= nbcols loop
sqlpart := sqlpart || ', ' ||cols(currentcolnumber);
currentcolnumber := currentcolnumber +1;
end loop;
EXECUTE IMMEDIATE 'SELECT * from (SELECT '|| firstcol ||' FROM '||tableName ||' WHERE ' || whereCond|| ' ORDER BY '|| firstcol || ') WHERE ROWNUM = 1 ' INTO firstresult;
while firstresult is not null
loop
big_query_str := big_query_str || ' UNION ' || 'SELECT * from ( SELECT '|| sqlpart ||' FROM '||tableName||' WHERE '|| firstcol ||' > '''|| firstresult||''' AND ' || whereCond|| ' ORDER BY '|| firstcol || ') WHERE ROWNUM = 1 ';
EXECUTE IMMEDIATE 'SELECT * from ( SELECT ' || firstcol ||' FROM '||tableName ||' WHERE '|| firstcol ||' > '''|| firstresult||''' AND '|| whereCond|| ' ORDER BY '|| firstcol || ') WHERE ROWNUM = 1' INTO firstresult;
end loop;
return big_query_str;
END small_distinct;
这个函数编译得很好,但是当函数返回时,我的varchar big_query_str为null
正如您在我的函数中看到的,这个varchar不可能为null,因为我在第18行用一个值初始化它
我试图删除这些行以发现问题所在,只有在删除第24行的while循环时,返回值才不是null
至少有人告诉我什么样的事件可以重置PL/SQL中的varchar吗?我不确定这一点,但您的大查询被定义为长度为10000的varchar2。返回SQL时,varchar2允许的最大长度为4000个字符。那么,这也许是一个问题?您是否可以尝试将big_query_str定义为CLOB类型,然后在对函数进行必要的更改后从函数返回它尝试将此循环包括在BEGIN/EXCEPTION/END中。是否有可能在这个循环中发生错误,并且返回big\u query\u str未执行
BEGIN
while firstresult is not null
loop
big_query_str := big_query_str ||........
EXECUTE IMMEDIATE....
end loop;
return big_query_str;
EXCEPTION
WHEN OTHERS THEN
return 'ERROR';
END;
尝试在第一个结果行周围添加异常处理程序 开始 执行立即的“SELECT*from SELECT”| | firstcol | | |和“| | WHERCOND | | ORDER BY”| |表格名| | | | | | | |其中ROWNUM=1”进入FIRSTRESSULT; 未找到数据时出现异常 出口 结束
在我看来,它将继续运行到最后一条记录,然后得到一个未找到的数据,因为在firstcol>firstresult中没有更多的记录。您从哪个客户端运行它?您如何调用它,以及您将返回值分配给什么?如果该分配目标小于10000个字符,为什么是varchar而不是更普通的varchar2?,或者您是从普通SQL调用它,则分配将失败;可能你正在压扁在那一点上得到的ORA-06502错误?或者字符串结束为>10000个字符,而您的调用者仍在压扁该错误?可能是好建议的重复,但更多信息是返回“error:”| | sqlerrm感谢你们两位的时间:,这有助于我在这个问题上取得进展。好的。。。我现在无法证实,但它看起来完全是真的。事实上,我来自PGPL/SQL,这种情况是不可能的。我忘记了select into必须返回一些东西,我的算法是让它失败:我以为plsql中的最大值是32000?但是,这个解决方案不够好,在某些情况下,我可以轻易地打破32k字符。在我的实际函数中,我不返回big_query_str,但我执行它以将其作为sys游标返回。经过进一步研究,对于生成大于32k字符的请求,我可以使用以下语法:执行立即sqlpart1 | | sqlpart2。我相信我能设法减少我的要求。