在数据库A上:我通过oracle sql exp.exe命令创建test.dmp:
exp.exe %CONNECT% FILE=test.dmp LOG=%LOGFILE% DIRECT=Y STATISTICS=NONE
在.log文件中写道:
. . export table TBL_TEST 7000 rows exported (no error!).
版本:Oracle Database 11g企业版11.2.0.4.0版 - 64位生产
在数据库B上:我通过imp.exe命令导入test.dmp:
imp.exe %CONNECT% file=test.dmp LOG=%LOGFILE% FULL=Y
在.log文件中,我看到错误:
. . importing table TBL_TEST
IMP-00019: row rejected due to ORACLE error 1400
IMP-00003: ORACLE error 1400 encountered
ORA-01400: cannot insert NULL into (TBL_TEST.COLUMN_A)
版本:Oracle Database 11g企业版11.2.0.4.0版 - 64位生产
TBL_TEST.COLUMN_A类型为NUMBER(1,0),Nullable = No,DATA_DEFAULT = 0。
这怎么可能?在数据库A上,“COLUMN_A”列已填充,并且还定义为非空。 所有表都在数据库B上从头开始重新创建。
你知道为什么会这样吗?
提前谢谢你,
Luisa Bradusca
答案 0 :(得分:0)
这看起来有问题的列已添加到已有数据的现有表中。在以前的版本中,这可能非常慢。如果没有指定默认值,则会添加该列,通过更新为所有现有行设置其值,然后才能添加非空约束。使用默认值,更新将自动发生,但仍需要时间。
在11g中,Oracle消除了这种痛苦when you specify a default value。这使得列添加几乎是即时的,并且对查询是透明的。这解释为in the documentation:
如果为NOT NULL列指定DEFAULT子句,则默认值将存储为元数据,但列本身不会填充数据。但是,将重写指定新列的后续查询,以便在结果集中返回默认值。
遗留exp
工具并不能理解这一点;它导出列中的值,对于旧行,它将为null。
您需要使用the datapump export tool,expdp
- 这将包括转储数据中的默认值,因此它将正确插入数据库B表中。然后你需要使用impdp
来导入。