将列数据类型为 varchar2 的表数据插入列数据类型为数字的表中

Posted

技术标签:

【中文标题】将列数据类型为 varchar2 的表数据插入列数据类型为数字的表中【英文标题】:Insert table data with column datatype varchar2 to a table with column datatype as number 【发布时间】:2017-06-01 14:02:17 【问题描述】:

在 oracle DB 中,我有一个表 TABLE1,其列数据类型定义为 VARCHAR2(50)。我有另一个表 TABLE2,其列数据类型定义为 NUMBER。 TABLE1 中存在的行数约为 23k,它们似乎都是数字。但是当我尝试插入命令时,出现以下错误。

    Error report -
SQL Error: ORA-01722: invalid number
01722. 00000 -  "invalid number"
*Cause:    
*Action:

这显然意味着有几行不是数字。但我无法识别那些没有数字的情况。如何识别非数字行。

附注: Oracle 数据库版本:9.2.0.8.0

是的,我知道它很古老。

【问题讨论】:

它们“似乎是”纯整数,还是有分组和/或小数分隔符?如果它们有分隔符,您的会话 NLS 设置是否与这些匹配(特别是 NLS_NUMERIC_CHARACTERS)? 也许 select col from table1 where translate(col,'.0123456789',' ') is not null; 我认为翻译是在 9 中 它们是纯整数,中间没有小数点。 【参考方案1】:

为什么要将数字存储在字符串中?这是根本问题。

您可以使用where 子句避免这些行:

insert into table2( . . .)
    select . . .
    from table1 t1
    where regexp_like(numbercol, '^[0-9]+$')

这假定“数字”表示“非负整数”。显然,该模式可以推广到其他范围和/或数字格式。

您可以通过运行类似的select 来识别非数字行:

    select . . .
    from table1 t1
    where not regexp_like(numbercol, '^[0-9]+$')

【讨论】:

创建 TABLE1 的基表具有声明为 varchar2 数据类型的列。因此它的 TABLE1 有 varchar2。谢谢你的回答。但是我在Oracle 9i上我没有正则表达式功能。【参考方案2】:

以下是用于识别差异情况的 PL SQL 块。在我的例子中,特殊字符是双引号。有问题的情况很少,因此打印输出是可行的。如果有更多数量的差异情况,那么在表格列中捕获错误消息将很有帮助。

declare
cursor cur is
select * from TABLE1 ;           ----- cursor to loop through cases individually
begin
for rec in cur 
loop 
begin
insert into table2 (column1)
select to_number(column1)
from table1
where
column1=rec.column1 ;
exception when others
then
Dbms_Output.Put_Line('error for '||rec.column1||' '||substr(sqlerrm,0,150)); --- error msg with discrepancy case
end;
end loop;
end;
/

【讨论】:

但这有什么用。这对解决您的问题没有帮助 使用该块,我能够识别非数字情况。select to_number(column1) from table1 where column1=rec.column1 ; 将在行为非数字时引发异常。如果它是一个数字,那么该行将插入到表中 table2

以上是关于将列数据类型为 varchar2 的表数据插入列数据类型为数字的表中的主要内容,如果未能解决你的问题,请参考以下文章

如何将oracle表中的字段由integer 转变为varchar2(50)

T-SQL 查询将数据插入到具有可变列数的表中

检查雪花中的表架构更改

将列从 Varchar2 转换为 CLOB 后查询无法执行

Oracle:将 VARCHAR2 列更改为 CLOB

如何仅将列值插入前一千行