Oracle異常匯總


ORA-00000: 正常的成功的完成(操作)

ORA-00000: normal, successful completion

原因1: 正常執行完成。

Normal exit.

  • 狀態: 部分驗證。
  • 分析: 此異常多數為程序沒有執行SQL語句或者說成功執行完SQL語句,但人為或因邏輯有誤,非要使用相關方法程序去獲取Oracle的錯誤信息,得到此異常,實質是Oracle告知沒有異常產生,猜測是異常信息的默認值為這個。目前發現以下兩種情況:

    1. 存儲過程、PL/SQL塊等,使用sqlerrm獲取異常,如下例所示。【已驗證】

      declare v_sqlcode number; v_sqlerrm varchar2(4000); begin /* …… 相關執行代碼 …… */ v_sqlcode := sqlcode; v_sqlerrm := sqlerrm; dbms_output.put_line('本次的異常code:' || v_sqlcode || chr(10) || '本次的異常信息:' || v_sqlerrm); exception when others then rollback; v_sqlcode := sqlcode; v_sqlerrm := sqlerrm; dbms_output.put_line('本次的異常code:' || v_sqlcode || chr(10) || '本次的異常信息:' || v_sqlerrm); end; / 
    2. 使用OCI的C程序中,用erhms()函數(OCIErrorGet())獲得Oracle錯誤信息。【未驗證,網絡匯總】

  • 措施: 無。【如果是人為需要獲取該異常,則不用做任何操作;如果是邏輯有誤,那么需要調整不去此異常或者在遇到此異常時將其屏蔽去掉。】

    None

原因2: hosts文件配置錯誤。

  • 狀態: 未驗證,網絡匯總。
  • 分析: 這種錯誤通常由於數據庫是復制過來的,hosts文件中的ip對應的host name和當前的主機名不一致導致甚至hosts文件丟失,都會導致數據庫startup時報此錯。
  • 措施: 校驗hosts文件是否有錯或缺失,進行修改或補充。

    • hosts文件在不同系統中所處的目錄:

      Windows XP/2000/Vista/7/8/8.1/10 ==> C:\windows\system32\drivers\etc\
      Linux及其他類Unix操作系統 ==> /etc/
      

ORA-00001: 違反唯一約束條件 (string.string=>[擁有者].[約束名])

ORA-00001: unique constraint (string.string) violated

原因1: UPDATE或INSERT語句試圖插入重復的鍵。對於在DBMS MAC模式下配置的Trusted Oracle,如果在不同級別存在重復條目,您可能會看到此信息。

An UPDATE or INSERT statement attempted to insert a duplicate key. For Trusted Oracle configured in DBMS MAC mode, you may see this message if a duplicate entry exists at a different level.

  • 狀態: 已驗證。
  • 分析: 如下例所示,此異常一般為違反作用於表上的唯一約束或者主鍵約束導致,它們限制了表的一列或多列值的唯一性,不能插入重復數據。

    -- 創建測試表 create table ora_00001_1( a char(24) /*primary key*/, -- 亦可加注釋內信息實現添加主鍵約束 b number /*unique*/, -- 亦可加注釋內信息實現添加唯一約束 -- 增加主鍵約束 constraint ora_00001_1_a primary key (a) -- 亦可加注釋內信息實現添加唯一約束 /*, constraint ora_00001_1_b unique (b)*/ ); -- 亦可加注釋內信息實現添加主鍵約束 /*alter table ora_00001_1 add constraint ora_00001_1_a primary key (a);*/ -- 增加唯一約束 alter table ora_00001_1 add constraint ora_00001_1_b unique (b); -- 插入測試數據 insert into ora_00001_1(a, b) values ('1',1); insert into ora_00001_1(a, b) values ('2',2); commit; -- ORA-00001: 違反唯一約束條件 (C##LY.ORA_00001_1_A); insert into ora_00001_1(a, b) values ('1',3); -- ORA-00001: 違反唯一約束條件 (C##LY.ORA_00001_1_B) insert into ora_00001_1(a, b) values ('3',2); -- ORA-00001: 違反唯一約束條件 (C##LY.ORA_00001_1_A) update ora_00001_1 set a = '1' where a = '2'; -- ORA-00001: 違反唯一約束條件 (C##LY.ORA_00001_1_B) update ora_00001_1 set b = '2' where b = '1'; 
  • 措施: 刪除唯一約束限制或不插入重復值。

    Either remove the unique restriction or do not insert the key.

    • 如果分析確定此處唯一約束或主鍵約束不需要,那么則可使用下面語句刪除約束

      -- 查詢約束與索引信息 select a.owner 約束所有者, a.constraint_name 約束名, case a.constraint_type when 'P' then 'Primary key' when 'U' then 'Unique key' when 'C' then ' Check constraint on a table' when 'R' then 'Referential integrity' when 'V' then 'With check option, on a view' when 'O' then 'With read only, on a view' when 'H' then 'Hash expression' when 'F' then 'Constraint that involves a REF column' when 'S' then 'Supplemental logging' else 'unkown' end 約束類型, b.table_name 表名, b.column_name 列名, c.index_name 索引名, c.uniqueness 是否唯一索引/*, d.table_name 表名, d.column_name 列名*/ from user_constraints a, user_cons_columns b, user_indexes c/*, user_ind_columns d*/ where a.constraint_name = b.constraint_name and a.index_name = c.index_name /*and c.index_name = d.index_name*/ and a.owner = b.owner and a.owner = c.table_owner and a.owner = &"[擁有者]" and a.constraint_name = &"[約束名]"; -- 由於如果約束對應的唯一索引若是事先手工創建的,那么在刪除約束時索引不會被刪除,Oracle之后自動刪除自己隱式創建的索引。 -- 因此加上drop index,可確保一定將索引刪除。 alter table [表名] drop constraint [約束名] drop index; -- 如果是主鍵約束,有可能遇到有用作外鍵的情況,那么在刪除時仍會報=>ORA-02273: 此唯一/主鍵已被某些外鍵引用 -- 報錯后了解是否有問題,是否需去除此主鍵和外鍵,然后可考慮用下面語句刪除主鍵約束,會同時刪除外鍵約束 alter table [表名] drop constraint [約束名] cascade drop index; alter table [表名] drop primary key cascade drop index; 
    • 如果分析確定是值重復,那么需排查表數據與預執行的SQL語句的重復值沖突、同一個事務內執行的SQL語句之間的重復值沖突,去掉重復值的插入或更新。

  • 備注:
    1. 唯一約束與主鍵約束的同:
      • 都通過唯一索引來限制約束列的唯一性,確保任何使表中約束的列在行與行之間存在重復值的操作失敗
      • 若無事先創建好唯一索引,都會在創建唯一約束或主鍵約束時隱式創建同名的唯一約束
      • 有約束必定有索引(無法在保持約束存在的情況下刪除索引=>ORA-02429: 無法刪除用於強制唯一/主鍵的索引)
      • 有索引不一定有約束(只刪除約束但不刪除索引則仍然會限制索引列的值的唯一性)
    2. 唯一約束與主鍵約束的異:
      • 唯一約束允許在該列或多列上存在NULL值,但主鍵約束不能存在NULL值
      • 一個表只能創建一個主鍵約束,但可創建多個唯一約束
      • 主鍵可擴展作為外鍵,唯一約束不可

ORA-00017: 會話被要求設置跟蹤事件

ORA-00017: session requested to set trace event

原因1: 當前會話被要求通過另一個會話設置一個跟蹤事件

The current session was requested to set a trace event by another session.

  • 狀態: 來源ORA12_ERRMG。
  • 措施: 內部使用;無需操作。

    This is used internally; no action is required.

ORA-00018: 超出最大會話數

ORA-00018: maximum number of sessions exceeded

原因1: 所有會話狀態對象都在使用中

All session state objects are in use.

  • 狀態: 部分驗證。
  • 分析: 很明顯,系統中所有會話數目已經達到設置的SESSIONS值,因此准備要創建的會話無法成功創建,而這個會話包括有用戶建立連接至數據庫是產生的會話、后台進程產生的會話以及各類涉及到硬解析處理數據字典基表的DML、DDL語句產生的遞歸會話。
  • 措施: 增加SESSIONS初始化參數值。【是否需要增加SESSIONS值還需進行判斷,是否是由於此值過小而現實場景需要更大的值?】

    Increase the value of the SESSIONS initialization parameter.

    • 如果判斷確定是由於SESSIONS值過小導致,則需修改增大此參數值【已驗證】:

      alter system set 參數名=參數值 [comment='注釋'] [deferred] [scope=memory|spfile|both] [sid='sid|*']; /* comment='注釋',修改時可添加注釋,會在V$PARAMETER視圖的update_comment字段看到內容,和參數值生效情況保存一致; deferred,指定參數修改是否只對以后的會話生效(對當前建立的會話無效,包括執行此修改的會話),部分參數必須加此參數; scope=both,表示修改會立即生效且會修改spfile文件以確保數據庫在重啟后也會生效如果(以spfile啟動此項為缺省值); scope=memory,表示修改會立即生效但不會修改spfile文件,因此重啟后失效(以pfile啟動此項為缺省值,且只可設置這個值); scope=spfile,表示只修改spfile文件,在重啟實例后才生效(以spfile啟動且為靜態參數則必須設置此項值); sid='sid|*',默認是sid=*,可改為在集群環境中的一個指定的實例值。 */ -- 查看"ALTER SYSTEM修改模式"列值,根據結果進行修改 select name 參數名, case type when 1 then 'Boolean' when 2 then 'String' when 3 then 'Integer' when 4 then 'Parameter file' when 5 then 'Reserved' when 6 then 'Big integer' else 'unknown' end 參數類型, value "會話級(若可修改)或實例級參數值", display_value 展示值, isses_modifiable "是否可用ALTER SESSION修改", case issys_modifiable when 'IMMEDIATE' then '無論pfile還是spfile啟動,都可用"alter system set ' || name || '=&' || '新的參數值;"更改參數並立即生效。' when 'DEFERRED' then '無論pfile還是spfile啟動,都要用"alter system set ' || name || '=&' || '新的參數值 deferred;"更改參數並將在之后的會話中生效。' when 'FALSE' then case a.is_spfile when 0 then '使用pfile啟動,需手動修改pfile文件中對應參數值再重啟。' else '使用spfile啟動,可用"alter system set ' || name || '=&' || name || ' scope=spfile;"更改參數。更改將在后續的實例中生效(當前數據庫需重啟)。' end else '?' end "ALTER SYSTEM修改模式", isinstance_modifiable "是否不同實例間值可不同" from v$parameter, (select count(1) is_spfile from v$parameter t where t.name = 'spfile' and t.value is not null) a where name = 'sessions'; 
    • 如果判斷確定SESSIONS值合理,則需分析確定產生大量會話的原因,是否相關程序代碼建立了連接未釋放?或者其它原因等。【待完善】

  • 備注: 參數SESSIONS:

屬性 描述
參數類型 Integer
默認值 派生公式: 【?~11gR1】="(1.1 * PROCESSES) + 5)"; 【11gR2~12cR2】="(1.5 * PROCESSES) + 22"
可修改(不用重啟及時生效) 【?~11gR2】="否"; 【12cR1~12cR2】="可用ALTER SYSTEM修改"
取值范圍 【?~11gR1】="1~2^31"; 【11gR2~12cR2】="1~2^16(即1~65536)"
基礎參數

SESSIONS指定可以在系統中創建的最大會話數。因為每次登錄都需要一個會話,所以這個參數有效地確定了系統中最大並發用戶數。您應該始終將此參數顯式設置等於最大並發用戶數的估計值+后台進程數+遞歸會話數(大約占總數的10%)。

Oracle使用此參數的默認值作為其最小值。 將SESSIONS值設置成[1~默認值)不會觸發錯誤,因為Oracle會忽略此值直接使用默認值。

ENQUEUE_RESOURCES和TRANSACTIONS參數的默認值派生自SESSIONS。因此,如果增加SESSIONS的值,則應考慮是否也調整ENQUEUE_RESOURCES和TRANSACTIONS的值。 (請注意,從Oracle Database 10g release 2(10.2)起,ENQUEUE_RESOURCES已被廢棄。)

在共享服務器環境中,PROCESSES的值可能相當小。因此,Oracle建議您將SESSIONS的值調整為大約1.1 *總連接數。

ORA-00019: 超出最大許可會話數

ORA-00019: maximum number of session licenses exceeded

原因1: 所有許可會話都在使用中。

All licenses are in use.

  • 狀態: 部分驗證。
  • 分析: 很明顯,系統中並發用戶會話已經達到設置的LICENSE_MAX_SESSIONS值,因此准備要創建的用戶會話無法創建。
  • 措施: 增大LICENSE_MAX_SESSIONS初始化參數的值。【是否需要增加LICENSE_MAX_SESSIONS值還需進行判斷,是否是由於此值過小而現實場景需要更大的值?】

    Increase the value of the LICENSE MAX SESSIONS initialization parameter.

    • 如果判斷確定是由於LICENSE_MAX_SESSIONS值過小導致,則需修改增大此參數值,【詳情參見ORA-00018=>原因1=>措施,將SQL語句中name = 'sessions'修改為name = 'license_max_sessions'即可】
    • 如果判斷確定LICENSE_MAX_SESSIONS值合理,則需分析確定產生大量會話的原因,是否相關程序代碼建立了連接未釋放?或者其它原因等。【待完善】
  • 備注: 參數LICENSE_MAX_SESSIONS:

屬性 描述
參數類型 Integer
默認值 0
可修改(不用重啟及時生效) 可用ALTER SYSTEM修改
取值范圍 0~許可會話數
基礎參數
Oracle實時應用集群 多個實例可以具有不同的值,但是安裝數據庫的所有實例的總和應小於或等於該數據庫許可的會話總數。

LICENSE_MAX_SESSIONS指定允許的並發用戶會話的最大數量。達到此限制后,只有具有RESTRICTED SESSION權限的用戶才能連接到數據庫。無法連接的用戶收到表示系統達到最大容量的警告消息。

零值表示不強制執行並發使用(會話)許可。如果將此參數設置為非零數字,則可能還需要設置LICENSE_SESSIONS_WARNING(請參閱“LICENSE_SESSIONS_WARNING”)。

不要同時啟用並發使用許可和用戶許可,即LICENSE_MAX_SESSIONS與LICENSE_MAX_USERS兩參數值至少一個要設置為零。

ORA-00020: 超出最大進程數(string=>[最大進程數])

ORA-00020: maximum number of processes (string) exceeded

原因1: 所有進程狀態對象都在使用中。

All process state objects are in use.

  • 狀態: 部分驗證。
  • 分析: 很明顯,系統中進程數已經達到設置的PROCESSES值,因此准備要創建的用戶會話無法創建。
  • 措施: 增加PROCESSES初始化參數的值。【是否需要增加PROCESSES值還需進行判斷,是否是由於此值過小而現實場景需要更大的值?】

    Increase the value of the PROCESSES initialization parameter.

    • 如果判斷確定是由於PROCESSES值過小導致,則需修改增大此參數值,【詳情參見ORA-00018=>原因1=>措施,將SQL語句中name = 'sessions'修改為name = 'processes'即可】
    • 如果判斷確定PROCESSES值合理,則需分析確定產生大量進程的原因,是否相關程序代碼建立了連接未釋放?或者其它原因等。【待完善】
  • 備注: 參數PROCESSES:

屬性 描述
參數類型 Integer
默認值 【?~10gR2】="40~操作系統依賴數"; 【11gR1~11gR2】="100"; 【12cR1~12cR2】="該值是派生的,它通常取決於警報日志中報告的核心數。"
可修改(不用重啟及時生效)
取值范圍 6~操作系統依賴數
基礎參數
Oracle實時應用集群 多個實例可以具有不同的值。

PROCESSES指定可以同時連接到Oracle的最大操作系統用戶進程數。它的值應允許所有后台進程運行,如鎖,作業隊列進程和並行執行進程。

+

 

該參數派生了SESSIONS和TRANSACTIONS參數的默認值。因此,如果更改PROCESSES的值,則應評估是否要調整這些派生參數的值。

ORA-00439: 未啟用功能: 【功能名】

ORA-00439: feature not enabled: string

原因1: 指定的功能未啟用。

The specified feature is not enabled.

  • 狀態: 已驗證。
  • 分析: ORACLE:你要多給我點錢,知道不!
  • 措施: 不要嘗試使用此功能。

    Do not attempt to use this feature.

    • 哎,哥們,實在想用此項功能,那就換高版本換企業版之類有這個功能的數據庫吧。
    • 如果是別人庫導過來的,嗯,它的庫鄙視了下你的庫,擦把汗告訴別人導出時指定下低版本。

 

ORA-01502: 索引 '(SCHEMA名).(索引名)' 或這類索引的分區處於不可用狀態

ORA-01502: index 'string.string' or partition of such index is in unusable state

原因1: 試圖連接訪問被"直接負載?"或DDL語句操作標記為不可用狀態的索引或索引的分區

An attempt has been made to access an index or index partition that has been marked unusable by a direct load or by a DDL operation

  • 狀態: 已驗證。
  • 分析: 一般是因為在執行DML語句操作表數據時,表上用到了主鍵約束、唯一約束需要用到索引的或者是表上單獨設置了唯一索引的或者是其它情況需要處理到索引或索引分區的,而此時索引或索引分區卻是被標記為不可用狀態,導致想執行的操作無法執行而報錯。如下例所示:

    -- 創建表與主鍵 create table ora_01502_1(a number, b varchar2(30)); alter table ora_01502_1 add constraints pk_ora_01502_1_a primary key(a); -- 標記索引UNUSABLE alter index pk_ora_01502_1_a unusable; -- 執行插入語句報錯 insert into ora_01502_1 (a,b) values(1,'1'); -- 查看索引、約束狀態。索引不可用,約束生效 select t.status, t.* from user_indexes t where t.table_name = 'ORA_01502_1'; select t.status, t.* from user_constraints t where t.table_name = 'ORA_01502_1'; -- 創建表與唯一索引 create table ora_01502_2(a number, b varchar2(30)); create unique index pk_ora_01502_2_a on ora_01502_2(a); -- 標記索引UNUSABLE alter index pk_ora_01502_2_a unusable; -- 執行插入語句報錯 insert into ora_01502_2 (a,b) values(1,'1'); -- 查看索引狀態。索引不可用 select t.status, t.* from user_indexes t where t.table_name = 'ORA_01502_1'; 
  • 措施: DROP指定的索引,或REBUILD指定的索引,或REBUILD不可用的索引分區

    DROP the specified index, or REBUILD the specified index, or REBUILD the unusable index partition

    • 如果需要修復索引或索引分區,通過rebuild進行重建。
    • 如果需要去掉索引,通過drop命名刪除,如果有約束得先刪除約束(如果是創建約束時系統自動創建的索引會在刪除約束時一起刪除),然后再刪除索引(如果是創建約束前手工建立的索引,那么還需要手工維護進行刪除)

ORA-01722: 無效數字

ORA-01722: invalid number

原因1: 指定的數字無效

The specified number was invalid.

  • 狀態: 已驗證。
  • 分析: 究其根本在於,要執行的語句在人為顯式轉換或Oracle判斷決定隱式轉換,故意或非故意得使一個非數值類型且無法轉換為數值類型的值轉換為數值類型失敗導致的。如下幾例:

    • 顯式轉換:

      -- to_number、to_binary_float、to_binary_double轉換字符串為數值 select to_number('2017年') from dual; select to_binary_float('8.935M') from dual; select to_binary_double('0.001s') from dual; 
    • 隱式轉換:

      ---------涉及到數值類型列的賦值或函數需要函數數值類型結果的轉換--------- -- insert/update/merge等語句操作列值 -- 測試表 create table ora_01722_1( a number, b char(24), c varchar2(300) ); -- 插入賦值,無法隱式轉換成數值,報錯 insert into ora_01722_1(a) values ('111測試字符串'); -- 插入賦值,可以隱式轉換成數值,不報錯 insert into ora_01722_1(a, b) values ('111', 'bbb'); commit; -- 更新賦值,無法隱式轉換成數值,報錯 update ora_01722_1 set a = '222測試字符串'; -- decode由第三列的數值1確定了該函數輸出結果為數值類型 -- 當匹配到'a'返回1,結果為數值,不報錯 select decode('a', 'a', 1, 'b', 2, 'c', 'three', 0) test1 from dual; -- 當匹配到'c'返回'three',結果不為數值且無法轉換為數值,報錯 select decode('c', 'a', 1, 'b', 2, 'c', 'three', 0) test2 from dual; -- nvl由第一列輸入的數值確定了它在此時輸出的結果也會為數值類型 -- 當發現第一個值不為空時,就嘗試輸出后邊的值作為本次nvl函數操作后的數值結果,發現無法轉換為數值,報錯 select nvl(&請輸入數值, '測試') from dual; -- nvl2由第二列的2確定了它在此時輸出的結果也會為數值 -- 當不管結果是否為2,它都會講后邊的值進行測試轉換……所以無論是否輸入null都報錯 select nvl2(&無論是否null, 2, '測試') from dual; ---------涉及到與數值類型的比較或其它運算--------- -- 未比較到'三',不報錯 select decode(1, 1, 'one', 2, 'two', '三', 'three', 'zero') from dual; -- 比較到'三',報錯 select decode(3, 1, 'one', 2, 'two', '三', 'three', 'zero') from dual; -- 與數值進行算術運算,無法隱式轉換為數值,報錯 select 'a' + 2 from dual; -- 與ora_01722_1的數值類型列a進行比較,將右邊轉換為數值失敗,報錯 select * from ora_01722_1 t where t.a = 'a'; -- ora_01722_1列b與數值類型進行比較,將左邊轉換為數值失敗,報錯 select * from ora_01722_1 t where t.b = 2; 

      特別注意時靈時不靈的查詢,基本都類似於下面的情況,靈的時候是因為之前查詢的是部分表數據或部分視圖數據等,不靈的時候則是涉及到另一部分甚至是全表全視圖的數據,而由於未注意隱式轉換導致其中“臟數據”無法轉換成數值類型而報錯。根源不是數據臟,是使用者不注意字段類型的區分,所以我們不要依賴於Oracle的隱式轉換!

  • 措施: 指定一個有效的數字。

    Specify a valid number.

    • 根據分析的情況,明確是否需要主動轉換,是否數據存在問題,該是數值就傳數值,該是字符串就添加左右英文單引號包裹成字符串。
  • 備注: 當需要的時候,Oracle數據庫會自動將值從一種數據類型轉換為另一種(如CHAR、VARCHAR2、NCHAR、NVARCHAR2、BINARY_FLOAT、BINARY_DOUBLE就有可能隱式轉換為NUMBER)。由於以下原因,Oracle建議您指定顯式轉換,而不是依賴於隱式自動轉換:

    • 當您使用顯式數據類型轉換函數時,SQL語句更容易理解。
    • 隱式數據類型轉換可能會對性能產生負面影響,特別是如果列值的數據類型被隱式轉換為基本常量的數據類型,而不是主動轉為其它類型。
    • 隱式轉換要根據需要轉換時的上下文來決定,而且在每類場景中不一定產生一樣的效果。例如,從datetime值到varchar2值的隱式轉換可能會根據NLS_DATE_FORMAT參數的值返回意外的一年。
    • 隱式轉換的算法可能會隨着軟件版本和Oracle產品之間的變化而變化。顯式轉換的變化則更有預見性。
    • 如果在索引表達式中產生了隱式數據類型轉換,那么Oracle數據庫可能不會使用該索引,因為它是為轉換前數據類型定義的。這可能會對性能產生負面影響。

ORA-01747: 用戶.表.列、表.列或列格式無效

ORA-01747: invalid user.table.column, table.column, or column specification

原因1: 列名為關鍵字。

  • 狀態: 已驗證。
  • 分析: 一般為在SQL語句或存儲過程、函數等中使用到的此字段為oracle的保留關鍵字,且保留方式標識了此關鍵字在某些情況下,例如在DML中是否不允許作為標識符的。如下列情況:

    -- 查詢能做屬性但不能作為標識符或某些場景(如DML操作)下不能作為標識符的關鍵字 select t.* from v$reserved_words t where (t.res_semi = 'Y' or t.reserved = 'Y') and t.res_attr = 'N'; -- 根據上面關鍵字建表,為測試需要,實際使用時請避免將Oracle保留關鍵字作為表的字段! create table ora_01747_1 ( "TRIGGER" number, "WHERE" number, "REVOKE" number, "INCREMENT" number, "THEN" number, "FILE" number, "PRIOR" number, "CONNECT" number, "COMMENT" number, "SYSDATE" number, "ONLINE" number, "DECIMAL" number, "SESSION" number, "MODIFY" number, "IN" number, "@" number, "," number, "GRANT" number, "INTO" number, "VALIDATE" number, "." number, "ADD" number, "ORDER" number, "HAVING" number, "TO" number, "NULL" number, "RENAME" number, "LEVEL" number, "USER" number, "ANY" number, /*"ROWID" number, --不可作建表屬性*/ "SHARE" number, "MODE" number, "UNION" number, "/" number, "SET" number, "INDEX" number, "MAXEXTENTS" number, "VALUES" number, "|" number, "VIEW" number, "[" number, "WITH" number, "EXCLUSIVE" number, "ALTER" number, "FROM" number, "SELECT" number, "BY" number, "-" number, "MLSLABEL" number, "AND" number, "+" number, "ROWS" number, "CHECK" number, ":" number, "VARCHAR2" number, "IMMEDIATE" number, "CURRENT" number, "AS" number, "*" number, "TABLE" number, "LONG" number, "SYNONYM" number, "ASC" number, "UNIQUE" number, "LIKE" number, "DESC" number, "VARCHAR" number, "INITIAL" number, "CHAR" number, "=" number, "DROP" number, "AUDIT" number, "ROWNUM" number, "FLOAT" number, "COMPRESS" number, "OFFLINE" number, "NOT" number, "DELETE" number, "^" number, "BETWEEN" number, "EXISTS" number, "IDENTIFIED" number, "WHENEVER" number, "INTEGER" number, "SIZE" number, "NOWAIT" number, ")" number, "]" number, "NOCOMPRESS" number, "COLUMN" number, "ELSE" number, "FOR" number, "INTERSECT" number, "!" number, "PRIVILEGES" number, "SUCCESSFUL" number, "PCTFREE" number, "UPDATE" number, "ACCESS" number, "RESOURCE" number, "UID" number, "DATE" number, "NOAUDIT" number, "RAW" number, /*"&" number,--不可作建表屬性 */"OPTION" number, "ROW" number, "SMALLINT" number, "MINUS" number, "OF" number, "ON" number, ">" number, "INSERT" number, "DEFAULT" number, "ALL" number, "START" number, "IS" number, "CREATE" number, "DISTINCT" number, "LOCK" number, "CLUSTER" number, "GROUP" number, "PUBLIC" number, "OR" number, "<" number, "NUMBER" number, "(" number/* ,"" number --不可作建表屬性*/ ); -- 異常測試(不是所有屬性錯誤使用都會產生ORA-01747的異常,還可能產生ORA-00936、ORA-01788、ORA-01745等異常) -- ORA-01747: user.table.column, table.column 或列說明無效 select SET from ora_01747_1; update ora_01747_1 set NUMBER = 1; update ora_01747_1 set ,"NUMBER" = 1; insert into ora_01747_1("TRIGGER", ,WHERE) values(1, ,1); 
  • 措施: 在使用此字段時,添加英文雙引號("")包裹。

    • 通過下面語句可查詢此類關鍵字的使用情況:

      select a.table_name 表, a.column_name 原字段, '"' || a.column_name || '"' 使用需加雙引號, 'select "' || a.column_name || '" from ' || a.table_name || ' where rownum = 1;' 簡單查詢語句, b.reserved "是否不能作標識符", b.res_type "是否不能作類型名稱", b.res_attr "是否不能作屬性名稱", b.res_semi "是否某些環境(DML)不能作標識符", b.duplicate from user_tab_columns a, v$reserved_words b where a.column_name = b.keyword and b.res_semi = 'Y' -- and a.table_name = '表名' -- and a.column_name = '字段名' ; 
  • 備注: 實際使用時請避免將Oracle保留關鍵字作為表的字段!

原因2: DML語句缺失列或多逗號。

  • 狀態: 已驗證。
  • 分析: 一般為使用各種方式動態拼接SQL時,拼接有誤,使得insert語句或update語句中逗號分隔的左邊或右邊出現空,示例可參見上面原因1的分析代碼。
  • 措施: 檢查拼接邏輯,加上缺失字段或去除多余的逗號

ORA-02095: 無法修改指定的初始化參數

specified initialization parameter cannot be modified

原因1: 指定的初始化參數不可修改

The specified initialization parameter is not modifiable

  • 狀態: 已驗證。
  • 分析: 無法使用alter system set 參數名=參數值;修改初始化參數,一般是當前實例是以pfile啟動時,修改參數時出現此情況(當scope=spfile會提示ORA-32001錯誤);或者是以spfile啟動時,對靜態參數未用scope=spfile選項進行修改時出現此情況。
  • 措施: 不可用

    N/A

    • 實際上可通過select value from v$parameter t where t.name = 'spfile';或SQL*Plusshow parameter spfile;進行查詢,如果有值(spfile的文件位置)代表以spfile啟動,則可通過alter system set 參數值=參數名 scope=spfile;來修改;如果是沒值,以pfile啟動,則必須找到pfile文件打開進行手動編輯修改對應參數值。最終都得重啟實例才可生效。
  • 備注:

    • PFILE啟動init.ora參數文件默認位置:

      $ORACLE_HOME/dbs/init$ORACLE_SID.ora (Unix)
      %ORACLE_HOME%\database\init%ORACLE_SID%.ora (Windows)
      

ORA-02096: 指定的初始化參數不能使用此選項進行修改

ORA-02096: specified initialization parameter is not modifiable with this option

原因1: 雖然初始化參數是可修改的,但不能使用指定的命令進行修改。

Though the initialization parameter is modifiable, it cannot be modified using the specified command.

  • 狀態: 已驗證。
  • 分析: 數據庫啟動的初始化參數根據啟動參數文件pfile和spfile的不同,以及參數的本身要求的不同,在使用alter system set 參數名=參數值;時需要加不同的scope值、deferred限制應用范圍。如果這些配置選項選擇錯誤,則會導致無法修改。暫只發現需加deferred配置選項進行修改的參數未加時,報此錯,如下例所示:

    -- 報錯,必須加deferred配置選項 alter system set object_cache_max_size_percent=&新的參數值; 
  • 措施: 檢查DBA指南,了解有關參數可能被修改的范圍的信息

    Check the DBA guide for information about under what scope the parameter may be modified

    • 一般是加上deferred選項即可,可用下面語句查看具體情況

      alter system set 參數名=參數值 [comment='注釋'] [deferred] [scope=memory|spfile|both] [sid='sid|*']; /* comment='注釋',修改時可添加注釋,會在V$PARAMETER視圖的update_comment字段看到內容,和參數值生效情況保存一致; deferred,指定參數修改是否只對以后的會話生效(對當前建立的會話無效,包括執行此修改的會話),部分參數必須加此參數; scope=both,表示修改會立即生效且會修改spfile文件以確保數據庫在重啟后也會生效如果(以spfile啟動此項為缺省值); scope=memory,表示修改會立即生效但不會修改spfile文件,因此重啟后失效(以pfile啟動此項為缺省值,且只可設置這個值); scope=spfile,表示只修改spfile文件,在重啟實例后才生效(以spfile啟動且為靜態參數則必須設置此項值); sid='sid|*',默認是sid=*,可改為在集群環境中的一個指定的實例值。 */ -- 查看"ALTER SYSTEM修改模式"列值,根據結果進行修改 select name 參數名, case type when 1 then 'Boolean' when 2 then 'String' when 3 then 'Integer' when 4 then 'Parameter file' when 5 then 'Reserved' when 6 then 'Big integer' else 'unknown' end 參數類型, value "會話級(若可修改)或實例級參數值", display_value 展示值, isses_modifiable "是否可用ALTER SESSION修改", case issys_modifiable when 'IMMEDIATE' then '無論pfile還是spfile啟動,都可用"alter system set ' || name || '=&' || '新的參數值;"更改參數並立即生效。' when 'DEFERRED' then '無論pfile還是spfile啟動,都要用"alter system set ' || name || '=&' || '新的參數值 deferred;"更改參數並將在之后的會話中生效。' when 'FALSE' then case a.is_spfile when 0 then '使用pfile啟動,需手動修改pfile文件中對應參數值再重啟。' else '使用spfile啟動,可用"alter system set ' || name || '=&' || name || ' scope=spfile;"更改參數。更改將在后續的實例中生效(當前數據庫需重啟)。' end else '?' end "ALTER SYSTEM修改模式", isinstance_modifiable "是否不同實例間值可不同" from v$parameter, (select count(1) is_spfile from v$parameter t where t.name = 'spfile' and t.value is not null) a where name = &參數名小寫;

 

ORA-02437: 無法驗證 (【SCHEMA名】.【主鍵名】) - 違反主鍵

 

ORA-02437: cannot validate (string.string) - primary key violated

 

原因1: 嘗試使用重復值或空值驗證主鍵。

 

attempted to validate a primary key with duplicate values or null values.

 

  • 狀態: 已驗證。
  • 分析: 創建主鍵約束時啟用對已有數據的校驗,或創建主鍵約束時禁用對已有數據的校驗但約束對應的索引是唯一索引仍進行了校驗。校驗時表中約束列存在重復值或者空值(空值有疑慮,測試發現先校驗空值報ORA-01449: 列包含 NULL 值; 無法將其變更為 NOT NULL),以致無法創建主鍵而報錯,如下例所示:

    -- 創建表與主鍵 create table ora_02437_1(a number, b varchar2(30)); -- 插入重復數據 insert into ora_02437_1(a,b) values(1,'1'); insert into ora_02437_1(a,b) values(1,'1'); -- 創建主鍵報錯 alter table ora_02437_1 add constraints pk_ora_02437_1_a primary key(a) --(enable) (validate) -- 默認enable啟用約束,且默認validate對已有數據進行校驗 ; -- 創建主鍵限制不對已有數據進行校驗,仍然報錯 alter table ora_02437_1 add constraints pk_ora_02437_1_a primary key(a) enable novalidate ; -- 查看沒有索引,但約束使用須有索引,而在創建唯一約束時系統默認給創建唯一索引,所以上條語句會報錯 select t.status, t.* from user_indexes t where t.table_name = 'ORA_02437_1'; 
  • 措施: 在啟用主鍵之前,請刪除重復項和空值。

    remove the duplicates and null values before enabling a primary key.

    • 如果需要對已有數據進行校驗並添加主鍵,則需查詢表並清除重復項和空值,而后再創建主鍵約束。
    • 如果不需要對已有數據進行校驗,則需先創建普通索引,再創建主鍵約束且加novalidate限制。

      -- 先創建索引 create index pk_ora_02437_1_a on ora_02437_1(a) -- online --可同時加online參數保證創建索引的時候不阻塞DML操作,以免對運行中的系統造成影響 ; -- 再創建主鍵 alter table ora_02437_1 add constraints pk_ora_02437_1_a primary key(a) novalidate ; -- 清除重復項和空值后可再啟動對已有數據校驗 alter table ora_02437_1 modify constraint pk_ora_02437_1_a validate;

 

ORA-14048: 分區維護操作不能與其他操作組合

 

ORA-14048: a partition maintenance operation may not be combined with other operations

 

原因1: ALTER TABLE或ALTER INDEX語句試圖將分區維護操作(例如MOVE PARTITION)與某些其他非法的操作(例如ADD PARTITION或PCTFREE)組合

 

ALTER TABLE or ALTER INDEX statement attempted to combine a partition maintenance operation (e.g. MOVE PARTITION) with some other operation (e.g. ADD PARTITION or PCTFREE which is illegal

 

  • 狀態: 部分驗證,暫時只遇到下面分析中的例子。
  • 分析: ALTER TABLE或ALTER INDEX語句的參數之前有沖突,其它操作對分區維護的操作造成影響。有可能是人為執行設置的語句;亦有可能類似於下例情況,oracle拼接而成的語句:

    -- 創建測試表,在字段后加primary key,則是系統自動生成的約束和索引的名稱,而不是人為指定。 create table ora_14048(a number primary key, b varchar2(30)); -- 將測試表主鍵約束對應的索引設置為不可用狀態 alter index SYS_C009537 unusable; -- windows系統cmd窗口導出測試表 expdp C##LY/密碼@XE tables=ora_14048 dumpfile=ora_14048.dmp directory=data_pump_dir logfile=expdp_ora_14048.log -- 然后導入測試表 impdp INFA/密碼@XE remap_schema=C##LY:INFA dumpfile=ora_14048.dmp directory=data_pump_dir logfile=impdp_ora_14048.log -- 導入有錯,日志如下 ;;; Import: Release 11.2.0.2.0 - Production on 星期五 9月 1 10:43:59 2017 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. ;;; 連接到: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production 已成功加載/卸載了主表 "INFA"."SYS_IMPORT_FULL_01" 啟動 "INFA"."SYS_IMPORT_FULL_01": INFA/********@XE remap_schema=C##LY:INFA dumpfile=ora_14048.dmp directory=data_pump_dir logfile=impdp_ora_14048.log 處理對象類型 TABLE_EXPORT/TABLE/TABLE 處理對象類型 TABLE_EXPORT/TABLE/TABLE_DATA . . 導入了 "INFA"."ORA_14048" 0 KB 0 行 處理對象類型 TABLE_EXPORT/TABLE/CONSTRAINT/CONSTRAINT ORA-39083: 對象類型 CONSTRAINT 創建失敗, 出現錯誤: ORA-14048: 分區維護操作不能與其他操作組合 失敗的 sql 為: ALTER INDEX "INFA"."SYS_C009537" UNUSABLE ENABLE 作業 "INFA"."SYS_IMPORT_FULL_01" 已經完成, 但是有 1 個錯誤 (於 10:44:01 完成) -- 查詢該表索引和約束情況,發現狀態還是正常,索引約束都建立起來了。只是索引名約束名不一致,且索引未能與來源庫中一樣狀態為UNUSABLE。 select t.status, t.* from user_indexes t where t.table_name = 'ORA_14048'; select t.status, t.* from user_constraints t where t.table_name = 'ORA_14048'; 
  • 措施: 確保分區維護操作是ALTER TABLE或ALTER INDEX語句中指定的唯一操作;除處理分區之外的,分區表/索引的默認屬性的操作或指定表重命名(ALTER TABLE RENAME)的操作都可以隨意組合

    Ensure that a partition maintenance operation is the sole operation specified in ALTER TABLE or ALTER INDEX statement; operations other than those dealing with partitions, default attributes of partitioned tables/indices or specifying that a table be renamed (ALTER TABLE RENAME) may be combined at will

    • 人為執行設置的語句,那么還是主動拆開執行操作。
    • 如果是分析中提到的例子,那么猜測是由於oracle的程序內部的問題,未能正常拼接好執行語句,所以如果仍需要將該索引設置為不可用狀態,那么在目標庫里面同樣執行一下設置語句即可(注意,由於是系統生成的索引名,那么在導入到目標庫時也是由目標庫自主生成的索引名,因此會出現索引名稱不一致。需要查詢表在目標庫里真正的索引名稱,然后進行操作);如果不需要設置為不可用狀態,那么久不用執行:
      -- 但由於索引名稱不一致的問題,如果是導入的表空間或用戶等更大級別的數據,那么出現問題時估計就不清楚需要設置不可用狀態的索引具體對應的是哪個表了 -- 此時估計應該從來源庫中查詢到對應索引的所在表,然后再在目標庫中找到該表的索引獲取到索引名稱然后進行操作。 alter index SYS_C009554 unusable; 

 

ORA-14063: 唯一/主鍵約束條件關鍵字中存在無用索引

 

ORA-14063: Unusable index exists on unique/primary constraint key

 

原因1: 用戶嘗試添加或啟用主鍵/唯一約束於(多)列,但這些列上的索引存在有標記為Index Unusable的。

 

User attempted to add or enable a primary key/unique constraint on column(s) of a table on which there exists an index marked Index Unusable.

 

  • 狀態: 已驗證。
  • 分析: 約束要想有效,都必須通過索引來實現,創建約束時都會默認創建同名的索引或關聯到約束字段上已有的索引。索引通過alter index 索引名 unusable;可設置為不可用狀態,那么關聯的約束就無法正常啟用或者想在索引限制的字段上創建約束也是無法創建成功的。
  • 措施: 刪除現有索引或使用ALTER INDEX REBUILD重建它。

    Drop the existing index or rebuild it using ALTER INDEX REBUILD

    • 如果判斷確定,仍需要創建或啟用主鍵約束或唯一約束,那么則需執行alter index 索引名 rebuild;將索引重建或者先刪除該索引,然后再執行對應約束語句即可。
    • 如果判斷確定,此處不需要再創建或啟用約束,那么就不用管,讓這個索引繼續保持UNUSABLE,並保持對未來同樣的操作的抗拒狀態:);或者將索引刪除,那么以后有其他人想創建就不會再遇到這個問題了。

 

 

ORA-32001: 已請求寫入 SPFILE, 但是沒有正在使用的 SPFILE

 

ORA-32001: write to SPFILE requested but no SPFILE is in use

 

原因1: ALTER SYSTEM命令或內部自調整機制請求寫入SPFILE,但沒有使用SPFILE。

 

An ALTER SYSTEM command or an internal self-tuning mechanism requested a write to the SPFILE but no SPFILE was in use.

 

  • 狀態: 已驗證。
  • 分析: 一般是用ALTER SYSTEM命令修改參數時,使用scope=spfile選項進行修改,但是當前實例不是以SPFILE啟動的。
  • 措施: 使用SPFILE重新啟動實例,或執行ALTER SYSTEM SET SPFILE。

    Re-start the instance using an SPFILE, or execute ALTER SYSTEM SET SPFILE.

    • 如果仍想用scope=spfile修改參數,那么則需用SPFILE文件重新啟動實例,或者直接用命令alter system set spfile = 'spfile文件在操作系統中的位置';
  • 備注:

    • PFILE啟動init.ora參數文件默認位置:

      $ORACLE_HOME/dbs/init$ORACLE_SID.ora (Unix)
      %ORACLE_HOME%\database\init%ORACLE_SID%.ora (Windows)
      
    • SPFILE文件初始默認位置:

      $ORACLE_HOME/dbs/spfile$ORACLE_SID.ora (Unix)
      %ORACLE_HOME%\database\spfile%ORACLE_SID%.ora (Windows)
      
    • 根據PFILE文件創建SPFILE文件:

      create spfile from pfile;-- 按默認位置找pfile
      create spfile from pfile = '指定一個其它文件路徑';
      
      • 根據SPFILE文件創建PFILE文件:
      create pfile from spfile;-- 按默認位置找spfile
      create pfile from spfile = '指定一個其它文件路徑';

 

 

ORA-39083: 對象類型 (對象類型名) 創建失敗, 出現錯誤:\n(錯誤描述)\n(失敗的sql為):\n(SQL語句)

 

ORA-39083: Object type string failed to create with error:\nstring\nFailing sql is:\nstring

 

原因1: 檢查原始錯誤代碼以確定實際原因。

 

Examine original error code to determine actual cause

 

  • 狀態: 已驗證。
  • 分析: 此項異常只是一個橋梁,需關注“出現錯誤”后的實際對應錯誤編碼和執行失敗的SQL語句,如下例所示,為在執行impdp導入數據時產生的異常:

    -- 此時出現的ORA-39083不需要關注,只需分析后邊的ORA-14048及失敗的SQL語句 …… …… ORA-39083: 對象類型 CONSTRAINT 創建失敗, 出現錯誤: ORA-14048: 分區維護操作不能與其他操作組合 失敗的 sql 為: ALTER INDEX "C##LY"."SYS_C00136360" UNUSABLE ENABLE …… …… 
  • 措施: 原始錯誤代碼將包含更多信息(分析原始錯誤代碼,具體情況具體對待)。

    Original error code will contain more information

 

ORA-39151: 表 ("String"."String"=>["SCHEMA名"."表名"])已存在。由於TABLE_EXISTS_ACTION參數值設置為SKIP, 將跳過所有相關元數據和數據

 

ORA-39151: Table "String"."String" exists. All dependent metadata and data will be skipped due to table_exists_action of skip

 

原因1: 相關表已存在。

 

  • 狀態: 已驗證,疑未記錄在ORACLE異常文檔中。
  • 分析: 不一定是錯誤,某種程度上是一個ORACLE的提示警告信息,在利用ORACLE的impdp命令導入表的時候可能遇到,是因為出現dump文件中的需要導入的表已經在數據庫用戶schema下存在了,而你在使用impdp命令時未指定TABLE_EXISTS_ACTION的參數值,ORACLE雖然默認將值設置為了SKIP,但它發現有沖突的表仍然提示告訴你此處需要根據實際情況自主選擇參數值,如下例所示:

    -- 創建測試表 create table ora_39151(a number); -- windows系統cmd命令窗口執行導出ora_39151的dump文件 expdp C##LY/密碼@XE tables=ora_39151 dumpfile=ora_39151.dmp directory=data_pump_dir logfile=expdp_ora_39151.log -- 測試導入 impdp C##LY/密碼@XE tables=ora_39151 dumpfile=ora_39151.dmp directory=data_pump_dir logfile=impdp_ora_39151.log -- 得到異常,impdp_ora_39151.log信息如下所示 ;;; Import: Release 11.2.0.2.0 - Production on 星期四 8月 31 20:33:27 2017 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. ;;; 連接到: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production 已成功加載/卸載了主表 "C##LY"."SYS_IMPORT_TABLE_01" 啟動 "C##LY"."SYS_IMPORT_TABLE_01": C##LY/********@XE tables=ora_39151 dumpfile=ora_39151.dmp directory=data_pump_dir logfile=impdp_ora_39151.log; 處理對象類型 TABLE_EXPORT/TABLE/TABLE ORA-39151: 表 "C##LY"."ORA_39151" 已存在。由於跳過了 table_exists_action, 將跳過所有相關元數據和數據。 處理對象類型 TABLE_EXPORT/TABLE/TABLE_DATA 作業 "C##LY"."SYS_IMPORT_TABLE_01" 已經完成, 但是有 1 個錯誤 (於 20:33:31 完成) 
  • 措施: 分析實際情況,判斷是否需要導入dump文件中對應沖突表的元數據及數據信息。

    • 如果確定不導入此類沖突表的數據,則不用進行任何操作,可忽視上面的錯誤,當然加上TABLE_EXISTS_ACTION=skip,亦可不出現錯誤,但任然會有提示信息:

      -- 設置skip值重新測試導入 impdp C##LY/密碼@XE tables=ora_39151 dumpfile=ora_39151.dmp directory=data_pump_dir logfile=impdp_ora_39151.log -- 未得到異常,impdp_ora_39151.log信息如下所示 ;;; Import: Release 11.2.0.2.0 - Production on 星期四 8月 31 20:40:44 2017 Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved. ;;; 連接到: Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production 已成功加載/卸載了主表 "C##LY"."SYS_IMPORT_TABLE_01" 啟動 "C##LY"."SYS_IMPORT_TABLE_01": C##LY/********@XE tables=ora_39151 dumpfile=ora_39151.dmp directory=data_pump_dir logfile=impdp_ora_39151.log table_exists_action=skip 處理對象類型 TABLE_EXPORT/TABLE/TABLE 表 "C##LY"."ORA_39151" 已存在。由於跳過了 table_exists_action, 將跳過所有相關元數據和數據。 處理對象類型 TABLE_EXPORT/TABLE/TABLE_DATA 作業 "C##LY"."SYS_IMPORT_TABLE_01" 已於 20:40:46 成功完成 
    • 如果確定要導入此類沖突表的數據甚至元數據,則需重新執行導入操作,根據備注的描述選擇其它參數進行處理。

  • 備注: TABLE_EXISTS_ACTION參數值:

    • SKIP: 表示跳過此表繼續處理下個對象。
    • APPEND: 表示在現有表數據行后追加dump文件中數據。
    • TRUNCATE: 表示刪除現有表中數據,然后導入dump文件中數據。
    • REPLACE: 表示刪除現有的表,然后從dump文件創建該表並導入數據。

 

 

 

持續更新中,可參見https://hnuhell.gitbooks.io/oracle_errmg/content/https://hnuhell.github.io/Oracle_ERRMG/上的頁面,博客更新較慢

 

作者:滾雪球俱樂部-何理利

出處: http://www.cnblogs.com/snowballed/

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。
如有疑問, 可郵件(he.lili1@ztesoft.com)咨詢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM