ITPub博客

首页 > 数据库 > Oracle > 关于Oracle9i中timestamp数据类型的一个bug

关于Oracle9i中timestamp数据类型的一个bug

原创 Oracle 作者:yaanzy 时间:2006-04-17 16:10:13 0 删除 编辑

今天在网友blog上看到一片文章描述通过数据库链使用CTAS建表时,如果在源表中含有
timestamp类型的列,则新创建的表的timestamp列的精度被置为最小即timestamp(0)
Bug 2417643,该bug在10g中已经被修正过来,下面是我在9204中的测试验证

[@more@]

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博客 ” ,链接:http://blog.itpub.net/3898/viewspace-827999/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    108
  • 访问量
    761550