ORA-06502:PL / SQL:数字或值错误:字符到数字的转换

时间:2019-04-14 04:26:55

标签: oracle plsql

我用下面的代码创建了一个函数,用于检索表中每一列的空格计数...但是,我在执行多行时遇到错误,无法解决错误转换的问题

set SERVEROUTPUT on
select  table_name,column_name,
get_rows( table_name,column_name) cnt
from all_tab_columns where table_name='TEST' 
/

错误:

ORA-06502: PL/SQL: numeric or value error: character to number conversion error
ORA-06512: at "JAMES.GET_ROWS", line 31
ORA-01722: invalid number
ORA-06512: at "JAMES.GET_ROWS", line 24
ORA-06512: at "JAMES.GET_ROWS", line 24
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    An arithmetic, numeric, string, conversion, or constraint error
           occurred. For example, this error occurs if an attempt is made to
           assign the value NULL to a variable declared NOT NULL, or if an
           attempt is made to assign an integer larger than 99 to a variable
           declared NUMBER(2).
*Action:   Change the data, how it is manipulated, or how it is declared so
           that values do not violate constraints.




create or replace function get_rows( l_table in varchar2,l_column_name in varchar2 ) return number
        as
          l_session_name varchar2 ( 30 )   := 'UNDEFINED';
          l_owner        varchar2 ( 30 )   := 'JAMES';
          --l_table        varchar2(30)      := 'TEST';
          l_cnt          NUMBER        default NULL;
          sql_stmt       varchar2 ( 1000 ) := null;
          l_space        varchar2 ( 30 )   := ' ';
        begin
          select sys_context ( 'userenv','session_user' )
          into l_session_name
          from dual;
            for i in
          (select owner, table_name,column_name
          from all_tab_columns
          where table_name = l_table
          and owner         = l_owner
          and column_name = l_column_name
          order by column_id 
          )
          loop
            sql_stmt := 'SELECT COUNT('||i.column_name||') FROM ' || i.owner ||'.' || i.table_name || ' WHERE ' ||i.column_name|| '='||''' ''' ;

             execute immediate sql_stmt into l_cnt;

            end loop;
           return l_cnt ;
           EXCEPTION
          WHEN OTHERS THEN
            dbms_output.put_line('Returning Error : '||SQLERRM);
            RETURN SQLERRM;

        end;

    /

3 个答案:

答案 0 :(得分:1)

错误消息引用了line 31,其中代码包含RETURN SQLERRM;,该代码试图返回alpha-numeric string,而函数必须返回number,您已经可以看到错误消息由 dbms_output.put_line('Returning Error : '||SQLERRM);,因此将RETURN SQLERRM;转换为RETURN NULL;,并确实揭示了您的主要问题,这是引发的ORA-01722: invalid number

只要您的列的数据类型不是VARCHAR2NVARCHAR等,而是DATENUMBER等,就会出现这种情况。

因此,您可以将光标转换为

for i in
(
select owner, table_name, column_name, data_type
  from all_tab_columns
 where table_name = l_table
   and owner = l_owner
   and column_name = l_column_name
 order by column_id
 )

并在循环内添加if语句为

if i.data_type in ('CHAR','VARCHAR2','VARCHAR','NCHAR','NVARCHAR2') then
  sql_stmt := 'SELECT COUNT('||i.column_name||') FROM ' || i.owner ||'.' || i.table_name || 
              ' WHERE ' ||i.column_name|| '='||''' ''' ;
else
  sql_stmt := 'SELECT COUNT('||i.column_name||') FROM ' || i.owner ||'.' || i.table_name || 
              ' WHERE ' ||i.column_name|| ' IS NULL';
end if;

每当您看到由于if语句而没有引发异常时,就可以完全删除异常部分。由于您最终的目标应该是摆脱此类异常。

答案 1 :(得分:0)

返回类型是问题

 return to_number(SUBSTR(sqlerrm, 5, 9));

答案 2 :(得分:0)

只需使用此:

begin
  ....
exception
  when others then
    DBMS_Output.Put_Line('Returning Error : ' || sqlerrm);
    return sqlcode;
end;

代替此:

begin
  ....
   EXCEPTION
  WHEN OTHERS THEN
    dbms_output.put_line('Returning Error : '||SQLERRM);
    RETURN sqlcode;

end;

问题是您在例外部分中的返回类型。 sqlerrm不是数字,因此在将函数的返回类型声明为数字时无法返回它。请改用sqlcode