我用下面的代码创建了一个函数,用于检索表中每一列的空格计数...但是,我在执行多行时遇到错误,无法解决错误转换的问题
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;
/
答案 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
。
只要您的列的数据类型不是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语句而没有引发异常时,就可以完全删除异常部分。由于您最终的目标应该是摆脱此类异常。
答案 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
。