今天在网友blog上看到一片文章描述通过数据库链使用CTAS建表时,如果在源表中含有
timestamp类型的列,则新创建的表的timestamp列的精度被置为最小即timestamp(0)
Bug 2417643,该bug在10g中已经被修正过来,下面是我在9204中的测试验证
1、在数据库A中创建源表
SQL> create table demo (d1 timestamp(6));
Table created
SQL> desc demo
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
D1 TIMESTAMP(6) Y
SQL> insert into demo(d1) values (timestamp'2005-04-17 14:12:03.234');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from demo;
D1
--------------------------------------------------------------------------------
17-4月 -05 02.12.03.234000 下午
2、在数据库B中创建目标表
SQL> create table demo as select * from demo@test2;
Table created
SQL> desc demo
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
D1 TIMESTAMP(0) Y
SQL> select * from demo;
D1
--------------------------------------------------------------------------------
17-4月 -05 02.12.03.234000 下午
上面结果果然如此,timestamp的精度变为0了,可是数据却仍然进入了表中,按道理这条数据有小数部分.234,插入后应该会被自动截断的,手工再插入一条:
SQL> insert into demo(d1) values (timestamp'2005-04-17 14:12:03.234');
1 row inserted
SQL> select * from demo;
D1
--------------------------------------------------------------------------------
17-4月 -05 02.12.03.234000 下午
17-4月 -05 02.12.03.234000 下午
还是能正确显示出来,小数部分没有被截断,另外建个表测试:
SQL> create table demo2 (d2 timestamp(0));
Table created
SQL> insert into demo2(d2) values (timestamp'2005-04-17 14:12:03.234');
1 row inserted
SQL> commit;
Commit complete
SQL> select * from demo2;
D2
--------------------------------------------------------------------------------
17-4月 -05 02.12.03 下午
发现确实是能截断小数部分,再看字段属性视图user_tab_cols:
SQL> select table_name,column_name,data_type,data_length from user_tab_cols p where p.table_name like '%DEMO%';
TABLE_NAME COLUMN_NAME DATA_TYPE DATA_LENGTH
------------- ------------- -------------- -----------
DEMO D1 TIMESTAMP(0) 11
DEMO2 D2 TIMESTAMP(0) 7
看来系统使用CTAS和dblink建表时,没有获取到远程表的timestamp精度信息,但是定义后台数据字典表时却又按照有精度的长度进行定义的,这和数据类型描述data_type相矛盾,会导致导出数据时,表定义的ddl中错误。我们可以通过包dbms_metadata.get_ddl来看表定义:
SQL> set long 5000
SQL> select dbms_metadata.get_ddl('TABLE','DEMO') from DUAL;
DBMS_METADATA.GET_DDL('TABLE',
--------------------------------------------------------------------------------
CREATE TABLE "DEV"."DEMO"
( "D1" TIMESTAMP (0)
) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
STORAGE(INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
TABLESPACE "USERS"
网友的参考网页:http://www.dbanotes.net/database/oracle_imp00020_1.html
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3898/viewspace-827999/ ,如需转载,请注明出处,否则将追究法律责任。