本人写了个简单的函数程序。如下:create or replace FUNCTION test(
    field_type IN varchar
) RETURN NUMBER 
AUTHID CURRENT_USER AS
    avg_plus        NUMBER;
    avg_negative   NUMBER;
    return_avg_date NUMBER;
    field           varchar2(30);
    table_name   varchar2(50);
BEGIN
         field := 'aa';
table_name := 'qqq';
SELECT avg(field) INTO avg_plus FROM table_name where field > 0;
SELECT avg(case when field < 0 then abs(field) end) INTO avg_negative FROM table_name; if avg_plus > avg_negative then
    return_avg_date := avg_plus;
else 
    return_avg_date := -1*avg_negative;
end if;
RETURN return_avg_date;
END test;
/
本函数编译时会报
15/2     PL/SQL: SQL Statement ignored
15/39    PL/SQL: ORA-00942: table or view does not exist 没有该表存在,但实际该表是存在的。然后把sql语句中的table_name 替换成表名qqq 编辑就过去了,但是运行(select test('1') from dual;)时又会报错。当把sql语句中的字段名用"aa"表示时才能正常工作。
这是为什么?不能用变量去替代字段or表名么? 请教高手如何能让变量替代表名,要不那么多表,就疯了~

解决方案 »

  1.   


    --------当字段名和表作为动态的时候,必须使用动态的sql执行
    create or replace FUNCTION test(field_type IN varchar) RETURN NUMBER AUTHID CURRENT_USER AS
      avg_plus        NUMBER;
      avg_negative    NUMBER;
      return_avg_date NUMBER;
      field           varchar2(30);
      table_name      varchar2(50);
    BEGIN
      field      := 'aa';
      table_name := 'qqq';
      execute immediate 'SELECT avg(field) FROM :table_name where :field > 0'
        into avg_plus
        using table_name, field;
      execute immediate 'SELECT avg(:field) FROM :table_name where :field > 0'
        into avg_plus
        using field, tablename, field;
      SELECT avg(case
                   when field < 0 then
                    abs(field)
                 end)
        INTO avg_negative
        FROM table_name;  if avg_plus > avg_negative then
        return_avg_date := avg_plus;
      else
        return_avg_date := -1 * avg_negative;
      end if;
      RETURN return_avg_date;
    END test;
    /
      

  2.   

    --field_type IN varchar2 参数怎么没看用到create or replace FUNCTION test(
                                    field_type IN varchar2
    ) RETURN NUMBER 
    AUTHID CURRENT_USER AS
        avg_plus        NUMBER;
        avg_negative      NUMBER;
        return_avg_date NUMBER;
        field           varchar2(30);
        table_name      varchar2(50);
         
    BEGIN
             field := 'aa';
        table_name := 'qqq';
    execute immediate 'SELECT avg('||field||')  FROM '||table_name||' where '||field||' > 0'  INTO avg_plus;
    execute immediate 'SELECT avg(case when '||field||' < 0 then abs('||field||') end)  FROM '||table_name INTO avg_negative;    if avg_plus > avg_negative then
            return_avg_date := avg_plus;
        else 
            return_avg_date := -1*avg_negative;
        end if;
        RETURN return_avg_date;
    END test;
      

  3.   

    向"Oraclefans_和wkc168"学习,呵呵,tks