PLSQL:varchar变量无任何理由变为null

时间:2013-07-22 13:05:14

标签: 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;
  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?

3 个答案:

答案 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类型,然后从函数中返回它(在对函数进行必要的更改之后)