Oracle SQL Developer-从游标获取值仅适用于一个筛选器(和/或)子句
我试图编写一个查询,从多个数据库检索一个值并将其写入一个文件。在我的函数中有一条语句,它从游标返回结果:Oracle SQL Developer-从游标获取值仅适用于一个筛选器(和/或)子句,sql,oracle,Sql,Oracle,我试图编写一个查询,从多个数据库检索一个值并将其写入一个文件。在我的函数中有一条语句,它从游标返回结果: cname := '(select count(unique(username)) from ' ||v_str_values(INDX)||'.APPLICATIONLOG where usertimestamp >= ''01-APR-21'') '; 当我试图修改过滤器以添加另一个过滤器时,结果为空: cname := '(select count(unique(userna
cname := '(select count(unique(username)) from ' ||v_str_values(INDX)||'.APPLICATIONLOG where
usertimestamp >= ''01-APR-21'') ';
当我试图修改过滤器以添加另一个过滤器时,结果为空:
cname := '(select count(unique(username)) from ' ||v_str_values(INDX)||'.APPLICATIONLOG where
usertimestamp >= ''01-APR-21'' AND usertimestamp <= ''01-MAY-21'') ';
以下是完整的功能:
create or replace FUNCTION FUNCTION2
RETURN varchar2
IS
TYPE cur_type IS REF CURSOR;
c_cursor cur_type;
counter number :=0;
cname varchar2(100) := '';
out_str_values varchar2(6000);
TYPE STR_LIST_TYPE IS TABLE OF VARCHAR2(6000);
v_str_values STR_LIST_TYPE;
BEGIN
v_str_values := STR_LIST_TYPE('ABC','DEF');
FOR INDX in v_str_values.FIRST..v_str_values.LAST
LOOP
BEGIN
cname := '(select count(unique(username)) from ' ||v_str_values(INDX)||'.APPLICATIONLOG where
usertimestamp >= ''01-APR-21'') ';
OPEN c_cursor FOR cname;
FETCH c_cursor into counter;
out_str_values := out_str_values || v_str_values(INDX) || ',' || counter || '/';
close c_cursor;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
END LOOP;
RETURN out_str_values;
END FUNCTION2;
为什么附加过滤器会删除结果
如果值大于2021-05-01 00:00:00
,则当过滤器仅为:
usertimestamp>='01-APR-21'
但当过滤器处于关闭状态时,将被排除在外
usertimestamp>='01-APR-21'和usertimestamp虽然您的日期处理(除其他事项外)有问题,应该解决,但这并不是在本例中返回null的原因。就其本身而言,双方都没有增加第二个条件
如果查看在函数中生成的动态语句(如图所示),使用示例模式名ABC和DEF,您将得到一个97个字符长的查询字符串*
添加第二个子句时,使用三个字符的模式名称,生成的查询字符串现在为130个字符
所以。。。尝试将字符串分配给cname
变量时,该变量定义为:
cname varchar2(100)
它将得到“ORA-06502:PL/SQL:数值或值错误:字符串缓冲区太小”。但这是在你的循环中发生的,它
EXCEPTION
WHEN OTHERS THEN
NULL;
因此错误被抑制,并且不会向out\u str\u values
变量追加任何内容,因此在循环之后返回null。(抑制异常,尤其是在其他异常
时抑制异常,通常是一个错误。)
如果您的值列表包含任何长度超过6个字符的值,则这些值也不会出现在较短查询的输出字符串中,但这可能不会发生,或者您可能没有注意到
因此,最直接的解决办法是将cname
的大小更改为足以容纳您生成的任何查询的大小
*基于代码中嵌入的查询的第二行,显示为缩进四个空格;如果是选项卡,则调整数字…请编辑问题并发布答案,而不仅仅是一行代码片段。这是如何调用和执行的?@OldProgrammer我补充了更多细节。对不起,如果它很难阅读。
EXCEPTION
WHEN OTHERS THEN
NULL;