Oracle常見錯誤——ORA-00942

根據前些天爲某大飛機公司導入某大飛機生產數據的經歷,準備寫篇關於Oracle導出文件DMP格式的分析,結果在本機導出一組演示數據時候,出現了錯誤,順便解決下。

本機裝的是Oracle 11g 32bit(11.0.6)的Client,主要是爲了使用ODT.Net 11.0.6.21,支持VS2008。但是採用EXP命令導出數據庫的時候,出現了些詭異的錯誤。

執行

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,但是我這樣改了以後,導入後想在哪個表空間就哪個表空間。

用這種方法修改了某大飛機的兩個數據庫導出文件,導入到同一個用戶模式下了,表空間全部統一,數據沒有丟失,導入過程完全沒用警告。

發佈了18 篇原創文章 · 獲贊 0 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章