尝试将一些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;
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
为空。
正如您在我的函数中所看到的,varchar
不可能为null,因为我在第18行用初始化它
我试图删除这些行以发现问题可能是什么,返回值不仅为空如果我删除while循环(第24行附近)
有人至少向我解释一下哪种事件可以重置PL / SQL中的varchar?
答案 0 :(得分:1)
尝试将此循环包含在BEGIN / EXCEPTION / END中。是否有可能在此循环中发生错误并且return big_query_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;
答案 1 :(得分:1)
尝试在firstresult行周围添加一个异常处理程序。
BEGIN
EXECUTE IMMEDIATE 'SELECT * from ( SELECT ' || firstcol ||' FROM '||tableName ||' WHERE '|| firstcol ||' > '''|| firstresult||''' AND '|| whereCond|| ' ORDER BY '|| firstcol || ') WHERE ROWNUM = 1' INTO firstresult;
EXCEPTION WHEN no_data_found THEN
EXIT;
END;
在我看来它会继续到最后一条记录,然后得到一个no_data_found,因为没有更多记录“firstcol&gt; firstresult”。
答案 2 :(得分:0)
我不确定这个,但你的big_query_str被定义为长度为10,000的varchar2。返回SQL时,varchar2的最大允许长度为4000个字符。那么,也许,这是一个问题?你能尝试将big_query_str定义为CLOB类型,然后从函数中返回它(在对函数进行必要的更改之后)