Oracle PLSQL:varchar变量无任何原因变为null

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

在尝试将一些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为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。我相信我能设法减少我的要求。