0

我正在运行一个基于基本条件子句检索行的基本查询,并不复杂。这工作正常:

<cfquery name="courses" datasource="banner">
        SELECT *
        FROM tjucatalog
        WHERE (course_status = 'Active')
            AND CONCAT(subject,course_no) IN (#PreserveSingleQuotes(courselist)#)
            AND term IN ('Fall 2012')
            AND ((end_date > #now()#) OR (course_meeting_info IS NOT NULL))
        ORDER BY TYear, TSort, DayNum, start_date, time, title
</cfquery>

但是,当我从查询中删除“AND term IN”行时,它会失败。

<cfquery name="courses" datasource="banner">
        SELECT *
        FROM tjucatalog
        WHERE (course_status = 'Active')
            AND CONCAT(subject,course_no) IN (#PreserveSingleQuotes(courselist)#)
            AND ((end_date > #now()#) OR (course_meeting_info IS NOT NULL))
        ORDER BY TYear, TSort, DayNum, start_date, time, title
</cfquery>

我得到的错误是:ORA-06502: PL/SQL: numeric or value error: string buffer too small ORA-06512: at "BANINST1.TJUCATALOG_PACK", line 519

这可能是一个需要包含字段“术语”的视图,还是我完全不知道这里还有其他东西在起作用?

4

2 回答 2

3

这似乎是在后台调用的包中的一个错误,可能从一个视图来看。您正在查询tjucatalog,并且返回的列之一实际上是函数调用的视图似乎是合理的。

问题不一定是term列。通过删除该条件,将返回更多行,并且针对条件存在时不存在的行中的列值调用该函数。但它可以是那些现在可见的行之一中的任何列。

作为可能发生的事情的一个简单而人为的例子:

create table t42 (id number, foo varchar2(20));

insert into t42 (id, foo) values (1, 'Short');
insert into t42 (id, foo) values (2, 'More than 10');

create package p42 as
function func(p_id in number) return varchar2;
end p42;
/

create package body p42 as
function func(p_id in number) return varchar2 is
    l_bar varchar2(10);
begin
    select foo into l_bar from t42 where id = p_id;
    return l_bar;
end func;
end p42;
/

create view v42 as select id, p42.func(id) as bar from t42;

所以我们有一个有两行的表,一个foo少于 10 个字符,另一个超过 10 个字符。我们有一个(愚蠢的)包函数,它接受一个id值,查找foo并返回它。以及使用该功能的视图。

这有效:

select * from v42 where id = 1;

        ID BAR
---------- --------------------
         1 Short

但是删除条件会导致它失败:

select * from v42;

ERROR:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SCOTT.P42", line 5

我的包体的第 5 行是select foo into l_bar from t42 where id = p_id;,问题是我声明l_bar为,这对于 . 的值varchar2(10)来说太小了。我应该宣布它为,甚至更好。fooid=2varchar2(20)t42.foo%TYPE

要查看有问题的函数在做什么,请查看源代码,如果您没有可用的数据库,您可以从数据库中获取(如果它没有被包装):

select line, text from all_source
where owner = 'BANINST1'
    and name = 'TJUCATALOG_PACK'
    and type = 'PACKAGE BODY'
order by line;
于 2012-07-02T16:26:40.043 回答
2

我们的 Oracle 专家返回并告诉我们他们必须将字段类型从 varchar2 (4000) 更改为 CLOB。缺少作为过滤子句的术语字段是一个红鲱鱼错误。我不知道查询中具体的哪个字段需要增加允许的长度,但它有效,所以我很高兴。

于 2012-07-03T13:32:51.237 回答