从您的上一条评论到@Ben's answer
'1234' 应该被认为是一个字符串并且失败
您似乎想在插入时对文字进行数据类型检查,并允许仅插入数字数据类型的文字。 Oracle 在有意义时会进行隐式数据类型转换。例如,您的表中有一个数字数据类型的列。当您尝试将字符文字 '123' 插入该列时,尽管该文字属于字符数据类型(char,简单字符文字属于 CHAR 数据类型而不是 varchar2,但操作仍将成功默认),因为 Oracle 查看列的数据类型,然后查看字符文字的数据类型和元素并决定“是的,将字符文字转换为数字是有意义的。 '并做到了。正如@Ben 所说,让您的应用程序检查您尝试插入表中的值是数字还是字符数据类型可能会更好。
话虽如此,进行数据类型检查并只允许插入数字数据类型的文字或变量的最简单方法可能是创建一个具有一个重载函数的包,例如isnumber()。该函数的第一个版本具有varchar2 数据类型的形参,其重载版本具有number 数据类型的形参。 Oracle会根据实际参数的数据类型选择合适的函数版本:
SQL> create or replace package Util1 as
2 function isnumber(p_val in varchar2)
3 return varchar2;
4 function isnumber(p_val in number)
5 return number;
6 end;
7 /
Package created
SQL> create or replace package body Util1 as
2 function isnumber(p_val in varchar2)
3 return varchar2 is
4 begin
5 raise_application_error(-20000, 'Not a numeric data type');
6 end;
7
8 function isnumber(p_val in number)
9 return number is
10 begin
11 return p_val;
12 end;
13 end;
14 /
Package body created
当您使用数字数据类型的实参调用util1.isnumber() 函数时,它只会将其返回,而当使用字符数据类型的实参调用该函数时,将引发异常。
SQL> create table t1(col number);
Table created
SQL> insert into t1(col) values(util1.isnumber(123));
1 row inserted
SQL> commit;
Commit complete
SQL> insert into t1(col) values(util1.isnumber('123'));
ORA-20000: Not a numeric data type
ORA-06512: at "HR.UTIL1", line 5
SQL> insert into t1(col) values(util1.isnumber('12345f'));
ORA-20000: Not a numeric data type
ORA-06512: at "HR.UTIL1", line 5
注意由于隐式数据类型转换,这种方法在触发器中不起作用。在触发器中,您必须执行以下操作:
:new.col_name := util1.isnumber(:new.col_name)
由于col_name 是number 数据类型,Oracle 将始终调用带有数字数据类型形式参数的isnumber() 函数版本,即使插入的实际值是(比如)'123',插入也会成功。