1. 程式人生 > >oracle 10g的long型別處理bug

oracle 10g的long型別處理bug

因為分割槽表監控的指令碼不想頻繁訪問dba_tab_subpartitions檢視,需要建立臨時表T1,偶然間發現oracle 10g的一個bug,在metalink上也沒能找到該問題的解決方案。

1.建立臨時表T1:

SQL> create table T1 as select table_name,partition_name,subpartition_name,to_lob(high_value) HIGH_VALUE from dba_tab_subpartitions;
Table created.

2.查詢有沒有資料:

SQL> select * from t1 where rownum < 3;

no rows selected

3.顯式插入資料時報錯 ORA-00932:

SQL> insert into t1 select table_name,partition_name,subpartition_name,to_lob(high_value) HIGH_VALUE from dba_tab_subpartitions;
insert into t1 select table_name,partition_name,subpartition_name,to_lob(high_value) HIGH_VALUE from dba_tab_subpartitions
                                                                  *

ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got LONG

NOTE:這是一個非常常見的long型別處理錯誤,官方說法:通過to_lob把long型別轉換為clob可以解決這個報錯。那麼就看一下是不是呢?

SQL> desc t1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 TABLE_NAME                                NOT NULL VARCHAR2(30)

 PARTITION_NAME                                     VARCHAR2(30)
 SUBPARTITION_NAME                                  VARCHAR2(30)
 HIGH_VALUE                                         CLOB

4.HIGH_VALUE列明明是clob型別,但是轉換卻不成功,trace10053看看insert語句內部是怎麼執行的:

SQL> alter session set events '10053 trace name context forever, level 1';
Session altered.

SQL> insert into t1 select table_name,partition_name,subpartition_name,to_lob(high_value) HIGH_VALUE from dba_tab_subpartitions;
insert into t1 select table_name,partition_name,subpartition_name,to_lob(high_value) HIGH_VALUE from dba_tab_subpartitions
                                                                  *
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got LONG

yuyan_ora_27952.trc顯示內部執行語句:

SELECT "PO"."NAME" "TABLE_NAME","PO"."SUBNAME" "PARTITION_NAME","SO"."SUBNAME" "SUBPARTITION_NAME",TO_LOB("TSP"."HIBOUNDVAL") "HIGH_VALUE" FROM "SYS"."OBJ$" "SO","SYS"."OBJ$" "PO", (SELECT "TABCOMPART$"."OBJ#" "OBJ#","TABCOMPART$"."DATAOBJ#" "DATAOBJ#","TABCOMPART$"."BO#" "BO#",ROW_NUMBER() OVER ( PARTITION BY "TABCOMPART$"."BO#" ORDER BY "TABCOMPART$"."PART#") "PART#","TABCOMPART$"."HIBOUNDLEN" "HIBOUNDLEN","TABCOMPART$"."HIBOUNDVAL" "HIBOUNDVAL","TABCOMPART$"."SUBPARTCNT" "SUBPARTCNT","TABCOMPART$"."FLAGS" "FLAGS","TABCOMPART$"."DEFTS#" "DEFTS#","TABCOMPART$"."DEFPCTFREE" "DEFPCTFREE","TABCOMPART$"."DEFPCTUSED" "DEFPCTUSED","TABCOMPART$"."DEFINITRANS" "DEFINITRANS","TABCOMPART$"."DEFMAXTRANS" "DEFMAXTRANS","TABCOMPART$"."DEFINIEXTS" "DEFINIEXTS","TABCOMPART$"."DEFEXTSIZE" "DEFEXTSIZE","TABCOMPART$"."DEFMINEXTS" "DEFMINEXTS","TABCOMPART$"."DEFMAXEXTS" "DEFMAXEXTS","TABCOMPART$"."DEFEXTPCT" "DEFEXTPCT","TABCOMPART$"."DEFLISTS" "DEFLISTS","TABCOMPART$"."DEFGROUPS" "DEFGROUPS","TABCOMPART$"."DEFLOGGING" "DEFLOGGING","TABCOMPART$"."DEFBUFPOOL" "DEFBUFPOOL","TABCOMPART$"."ANALYZETIME" "ANALYZETIME","TABCOMPART$"."SAMPLESIZE" "SAMPLESIZE","TABCOMPART$"."ROWCNT" "ROWCNT","TABCOMPART$"."BLKCNT" "BLKCNT","TABCOMPART$"."EMPCNT" "EMPCNT","TABCOMPART$"."AVGSPC" "AVGSPC","TABCOMPART$"."CHNCNT" "CHNCNT","TABCOMPART$"."AVGRLN" "AVGRLN","TABCOMPART$"."SPARE1" "SPARE1","TABCOMPART$"."SPARE2" "SPARE2","TABCOMPART$"."SPARE3" "SPARE3","TABCOMPART$"."PART#" "PHYPART#" FROM SYS."TABCOMPART$" "TABCOMPART$") "TCP", (SELECT "TABSUBPART$"."OBJ#" "OBJ#","TABSUBPART$"."DATAOBJ#" "DATAOBJ#","TABSUBPART$"."POBJ#" "POBJ#",ROW_NUMBER() OVER ( PARTITION BY "TABSUBPART$"."POBJ#" ORDER BY "TABSUBPART$"."SUBPART#") "SUBPART#","TABSUBPART$"."FLAGS" "FLAGS","TABSUBPART$"."TS#" "TS#","TABSUBPART$"."FILE#" "FILE#","TABSUBPART$"."BLOCK#" "BLOCK#","TABSUBPART$"."PCTFREE$" "PCTFREE$","TABSUBPART$"."PCTUSED$" "PCTUSED$","TABSUBPART$"."INITRANS" "INITRANS","TABSUBPART$"."MAXTRANS" "MAXTRANS","TABSUBPART$"."ANALYZETIME" "ANALYZETIME","TABSUBPART$"."SAMPLESIZE" "SAMPLESIZE","TABSUBPART$"."ROWCNT" "ROWCNT","TABSUBPART$"."BLKCNT" "BLKCNT","TABSUBPART$"."EMPCNT" "EMPCNT","TABSUBPART$"."AVGSPC" "AVGSPC","TABSUBPART$"."CHNCNT" "CHNCNT","TABSUBPART$"."AVGRLN" "AVGRLN","TABSUBPART$"."SPARE1" "SPARE1","TABSUBPART$"."SPARE2" "SPARE2","TABSUBPART$"."SPARE3" "SPARE3","TABSUBPART$"."HIBOUNDLEN" "HIBOUNDLEN","TABSUBPART$"."HIBOUNDVAL" "HIBOUNDVAL","TABSUBPART$"."SUBPART#" "PHYSUBPART#" FROM SYS."TABSUBPART$" "TABSUBPART$") "TSP","SYS"."TAB$" "T","SYS"."TS$" "TS","SYS"."SEG$" "S","SYS"."USER$" "U" WHERE "SO"."OBJ#"="TSP"."OBJ#" AND "PO"."OBJ#"="TSP"."POBJ#" AND "TCP"."OBJ#"="TSP"."POBJ#" AND "TCP"."BO#"="T"."OBJ#" AND BITAND("T"."TRIGFLAG",1073741824)<>1073741824 AND "TSP"."TS#"="TS"."TS#" AND "U"."USER#"="PO"."OWNER#" AND "TSP"."FILE#"="S"."FILE#" AND "TSP"."BLOCK#"="S"."BLOCK#" AND "TSP"."TS#"="S"."TS#" AND "PO"."NAMESPACE"=1 AND "PO"."REMOTEOWNER" IS NULL AND "PO"."LINKNAME" IS NULL AND "SO"."NAMESPACE"=1 AND "SO"."REMOTEOWNER" IS NULL AND "SO"."LINKNAME" IS NULL

顯然語法是不符合規則的!

SQL> alter session set events '10053 trace name  context off';
Session altered.

5.然後檢視metalink上沒有相關的內容,oracle不推薦用long型別,然而他自己卻總喜歡在一些系統表裡用long型別。那麼11g會不會也出現這個問題呢?

在11g上執行相同的語句,並記錄trace:
SQL> alter session set events '10053 trace name context forever, level 1';
Session altered.

SQL> create table T1 as select table_name,partition_name,subpartition_name,to_lob(high_value) HIGH_VALUE from dba_tab_subpartitions;
Table created.

SQL> desc t1;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 PARTITION_NAME                                     VARCHAR2(30)
 SUBPARTITION_NAME                                  VARCHAR2(30)
 HIGH_VALUE                                         CLOB

SQL> select * from t1 where rownum < 3;
TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------
SUBPARTITION_NAME
------------------------------
HIGH_VALUE
--------------------------------------------------------------------------------
WRI$_OPTSTAT_SYNOPSIS$         P0
SYS_SUBP1

WRI$_OPTSTAT_SYNOPSIS$         P0
SYS_SUBP2

TABLE_NAME                     PARTITION_NAME
------------------------------ ------------------------------
SUBPARTITION_NAME
------------------------------
HIGH_VALUE
--------------------------------------------------------------------------------

SQL> alter session set events '10053 trace name  context off';


yuyan_ora_30822.trc顯示內部執行語句:

SELECT "PO"."NAME" "TABLE_NAME","PO"."SUBNAME" "PARTITION_NAME","SO"."SUBNAME" "SUBPARTITION_NAME",TO_LOB("TSP"."HIBOUNDVAL") "HIGH_VALUE" FROM "SYS"."OBJ$" "SO","SYS"."OBJ$" "PO",SYS."TABCOMPART$" "TCP","SYS"."TABSUBPART$" "TSP","SYS"."TAB$" "T","SYS"."TS$" "TS","SYS"."SEG$" "S","SYS"."USER$" "U","SYS"."DEFERRED_STG$" "DS" WHERE "SO"."OBJ#"="TSP"."OBJ#" AND "PO"."OBJ#"="TSP"."POBJ#" AND "TCP"."OBJ#"="TSP"."POBJ#" AND "TCP"."BO#"="T"."OBJ#" AND BITAND("T"."TRIGFLAG",1073741824)<>1073741824 AND "TSP"."TS#"="TS"."TS#" AND "U"."USER#"="PO"."OWNER#" AND "TSP"."OBJ#"="DS"."OBJ#"(+) AND "TSP"."FILE#"="S"."FILE#"(+) AND "TSP"."BLOCK#"="S"."BLOCK#"(+) AND "TSP"."TS#"="S"."TS#"(+) AND "PO"."NAMESPACE"=1 AND "PO"."REMOTEOWNER" IS NULL AND "PO"."LINKNAME" IS NULL AND "SO"."NAMESPACE"=1 AND "SO"."REMOTEOWNER" IS NULL AND "SO"."LINKNAME" IS NULL

在11g中是可以執行成功的,看來oracle在11g對這個bug做了修改!