EXP-00008: 遇到 ORACLE 錯誤 904 ORA-00904: "MAXSIZE": invalid identifier
原因:oracle版本不一樣
執行
C:/>EXP plx/plx@orcl FILE=c:/plx.dmp TABLES=(s,sc,c)
結果報錯
Export: Release 11.1.0.6.0 – Production on 星期日 7月 26 12:42:19 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
連接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Production
With the Partitioning, OLAP and Data Mining options
已導出 ZHS16GBK 字符集和 UTF8 NCHAR 字符集
服務器使用 UTF8 字符集 (可能的字符集轉換)
即將導出指定的表通過常規路徑…
. . 正在導出表 S
EXP-00008: 遇到 ORACLE 錯誤 904
ORA-00904: “MAXSIZE”: invalid identifier
. . 正在導出表 SC
EXP-00008: 遇到 ORACLE 錯誤 1003
ORA-01003: no statement parsed
. . 正在導出表 C
EXP-00008: 遇到 ORACLE 錯誤 904
ORA-00904: “MAXSIZE”: invalid identifier
EXP-00008: 遇到 ORACLE 錯誤 942
ORA-00942: table or view does not exist
EXP-00024: 未安裝導出視圖, 請通知您的 DBA
EXP-00000: 導出終止失敗
很詭異,從來沒見過的錯誤,怎么會報沒有字段的錯誤呢。
於是Google(在技術資料方面BAIDU就是垃圾),
有個哥們說是數據字典丟了,我很詫異,我前幾天在Oracle 10g Client下導出過了,怎么會丟失數據字典,還是半信半疑的執行了。
在服務器上執行
oracle@linux-lrn6:~> sqlplus sys/sys@orcl as sysdba
SQL >@/opt/oracle/product/10.2/db_1/rdbms/admin/catexp.sql
以重建數據字典。
建好了后,再次執行導出,還是不行。
但是我在服務器上執行同樣的語句就可以。
於是我意識到可能是EXP版本問題,於是測試。
在一台11g的機器上運行一條SQL 檢 測那個MAXSIZE是個什么列。
SQL > select distinct table_name from user_col_comments where column_name=’MAXSIZE’;
TABLE_NAME
————————————————————
EXU9STOU
EXU9PLB
EXU9PDSU
EXU9LBCPU
EXU9PDS
EXU9IXCP
CPOOL$
EXU9TBCPU
EXU9TBCP
EXU9STO
EXU9IXCPU
TABLE_NAME
————————————————————
DBA_CPOOL_INFO
EXU9TBS
EXU9PLBU
EXU9LBCP
然后在10g的服務器上運行同樣的語句,沒有返回行。可見MAXSIZE是11g在數據字典中新加的項,10g是沒有的。
#10g
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – 64bit Production
With the Partitioning, OLAP and Data Mining options
SQL > desc sys.exu9tbs
名 稱 是否為空? 類型
—————————————– ——– —————————-
ID NOT NULL NUMBER
OWNER CHAR(6)
NAME NOT NULL VARCHAR2(30)
ISONLINE VARCHAR2(7)
CONTENT VARCHAR2(9)
INIEXT NOT NULL NUMBER
SEXT NOT NULL NUMBER
PCTINC NOT NULL NUMBER
MINEXT NOT NULL NUMBER
MAXEXT NOT NULL NUMBER
MINLEN NUMBER
DEFLOG NOT NULL NUMBER
EXT_MGT NOT NULL NUMBER
ALLOC_TYPE NOT NULL NUMBER
BLOCKSIZE NOT NULL NUMBER
#11g
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 – Production
With the Partitioning, OLAP and Real Application Testing options
SQL > desc sys.exu9tbs
名 稱 是否為空? 類型
—————————————– ——– ————————-
ID NOT NULL NUMBER
OWNER CHAR(6)
NAME NOT NULL VARCHAR2(30)
ISONLINE VARCHAR2(7)
CONTENT VARCHAR2(9)
INIEXT NOT NULL NUMBER
SEXT NOT NULL NUMBER
PCTINC NOT NULL NUMBER
MINEXT NOT NULL NUMBER
MAXEXT NOT NULL NUMBER
MINLEN NUMBER
DEFLOG NOT NULL NUMBER
EXT_MGT NOT NULL NUMBER
ALLOC_TYPE NOT NULL NUMBER
BLOCKSIZE NOT NULL NUMBER
MAXSIZE NUMBER ———>問題在這里
所以,導入導出數據的時候,還是盡可能的版本統一,10g導10g 的,11g導11g的,免得不必要的麻煩。
好了,言歸正傳,分析DMP格式。
DMP是什么詭異格式?就是上面Oracle的EXP工具導出的備份文件的格式。
某次腦子發燒用gVim打開DMP猛然發現它就是一些SQL , 令我非常詫異,於是發現了一些詭異的修改備份的方法,就是直接修改DMP文件。
下面我打開一個新鮮導出的備份文件,分析一下DMP的結構。
首先一打開DMP,最上面有幾行這樣的東西:
DPLX
RUSERS
8192
0
20
0
下面那些數字不要管,數據庫的一些參數,DPLX就是導出的用戶名,D是標識,PLX是用戶名,EUSERS是默認表空間,E是標識,USERS是 表空間。
繼續往下看,能看到這樣的語句:
sys.dbms_logrep_imp.instantiate_schema(schema_name=>SYS_CONTEXT(‘USERENV’,'CURRENT_SCHEMA’), export_db_name=>’ORCL.REGRESS.RDBMS.DEV.US.ORACLE.COM’, inst_scn=>’5603910′);
這個是建立模式的語句,原則上每個用戶就是一個模式,Schema。
這上面這些東西,最好都不要改,改了要出事的,一般導入就不行了,會失效,因為DMP雖然大部分是明文SQL ,但是也有一部分是二進制的,改了這里會影響校驗。
再往后看就有建表語句了,
CREATE TABLE “C” (“CNO” NUMBER(10, 0) NOT NULL ENABLE, “CNAME” VARCHAR2(20) NOT
NULL ENABLE, “CPNO” NUMBER(10, 0), “CCREDIT” NUMBER(3, 0) NOT NULL ENABLE) PCTF
REE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE(INITIAL 65536 FREELISTS 1 FREE
LIST GROUPS 1 BUFFER_POOL DEFAULT) TABLESPACE “USERS” LOGGING NOCOMPRESS
有時候導出的表空間混亂,就可以在黃色底色的那里改,替換成想要的表空間。
然后一個表下面就是插入數據的語句了:
INSERT INTO “C” (“CNO”, “CNAME”, “CPNO”, “CCREDIT”) VALUES (:1, :2, :3, :4)
再往下就是一堆二進制,就是要插入的數據,那個就改不了了,Oracle沒有公開格式。
不過知道這些已經足以解決導入中的很多問題,尤其是表空間混亂的問題。
某大飛機數據庫就非常混亂,一個ARJ用戶模式(我沒有泄密,公開的)下有來自ARJ,M3,USERS,SYSTEM等表空間的表,就是導入的時 候方法不正確。然后用上篇Oracle日志中取消權限的方法,也會有些表導不進去,這是Oracle的BUG,但是我這樣改了以后,導入后想在哪個表空間 就哪個表空間。
用這種方法修改了某大飛機的兩個數據庫導出文件,導入到同一個用戶模式下了,表空間全部統一,數據沒有丟失,導入過程完全沒用警告。