ORA-06502: PL / SQL: ошибка с числом или значением: преобразование символа в число - PullRequest
0 голосов
/ 14 апреля 2019

Я создал функцию с кодом ниже, чтобы получить количество пустых мест для каждого столбца в таблице ... однако я сталкиваюсь с ошибкой при выполнении для нескольких строк Не могу понять, где проблема с преобразованием ошибок

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 ]

1 голос
/ 14 апреля 2019

Сообщения об ошибках ссылаются на line 31, где код имеет RETURN SQLERRM;, который пытается вернуть alpha-numeric string, в то время как функция должна возвращать number, вы уже можете увидеть сообщение об ошибке: dbms_output.put_line('Returning Error : '||SQLERRM);, так что конвертируйте RETURN SQLERRM; в RETURN NULL;, и действительно выявите вашу главную проблему, это - ORA-01722: invalid number, которая возникает.

Это происходит, когда типы данных в ваших столбцах не VARCHAR2, NVARCHAR .. и т. Д., А DATE, NUMBER .. и т. Д.

Следовательно, вы можете конвертировать курсор в

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, вы можете полностью удалить часть исключения. Поскольку вашей конечной целью должно быть избавление от таких исключений.

0 голосов
/ 18 апреля 2019

просто используйте это:

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.

0 голосов
/ 14 апреля 2019

тип возврата - проблема

 return to_number(SUBSTR(sqlerrm, 5, 9));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...