ORA-00955 錯誤是什么?

ORA-00955 錯誤指的是 “名稱已由現(xiàn)有對象使用”。簡單來說,就是當你在 Oracle 數(shù)據(jù)庫中進行創(chuàng)建操作,比如創(chuàng)建表、視圖、存儲過程、同義詞等各類對象時,如果使用的名稱已經(jīng)被數(shù)據(jù)庫里其他對象占用了,就會出現(xiàn)這個錯誤提示,導(dǎo)致創(chuàng)建操作無法順利完成。例如,你想創(chuàng)建一個名為 “student2” 的存儲過程,可數(shù)據(jù)庫里已經(jīng)存在了同名的表或者其他類型的對象叫 “student2”,那這時就會觸發(fā) ORA-00955 錯誤啦。了解這個錯誤的基本含義,是我們后續(xù)尋找解決辦法的第一步哦。
常見引發(fā) ORA-00955 錯誤的場景
建表時出現(xiàn)該錯誤
在創(chuàng)建新表的時候,常常容易觸發(fā) ORA-00955 錯誤。比如,當我們想要創(chuàng)建一個結(jié)構(gòu)相似的測試表時,可能就會遇到這種情況。有時候我們覺得只要表名不重復(fù)就沒問題了,但其實不然,像主鍵名等等重復(fù)了也會引發(fā)該錯誤。例如,之前有用戶在數(shù)據(jù)庫建表時,更換了表名稱,可依然出現(xiàn) “ORA-00955: 名稱已由現(xiàn)有對象使用” 這樣的提示語,經(jīng)過一番排查后發(fā)現(xiàn),是在增加唯一值約束名的時候,和以前的相同了,從而導(dǎo)致無法進行創(chuàng)建。再比如,在建表的過程中設(shè)置主鍵約束時,如果使用的約束名稱與數(shù)據(jù)庫里已有的其他對象的名稱沖突,哪怕表本身的名稱是獨一無二的,同樣會觸發(fā)這個錯誤,使得建表操作不能順利完成呀。
修改主鍵時出現(xiàn)該錯誤
對表的主鍵進行修改操作時,也很容易出現(xiàn) ORA-00955 錯誤。以藥庫的 drug_stock 表為例,若需要在主鍵中增加一個字段,如 PUTINSTORAGE_DATE,原來的主鍵名是 PK_DRUG_STOCK,鍵值為 DRUG_CODE、DRUG_SPEC、FIRM_ID、PACKAGE_SPEC、BATCH_NO、STORAGE,修改后要變?yōu)榘略鲎侄蔚男问?。在?zhí)行刪除原主鍵的操作 “ALTER TABLE PHARMACY.DRUG_STOCK DROP PK_DRUG_STOCK;” 以及后續(xù)相關(guān)刪除主鍵索引等操作后,準備添加新主鍵時,如果新添加主鍵的相關(guān)名稱,像主鍵名或者與之關(guān)聯(lián)的索引名等,和數(shù)據(jù)庫中已有的其他對象名稱產(chǎn)生沖突,就會出現(xiàn) ORA-00955 錯誤,導(dǎo)致主鍵修改無法成功完成。又或者要添加的主鍵列名,在表中的數(shù)據(jù)存在重復(fù)情況,那在執(zhí)行添加主鍵語句時,也會報添加主鍵失敗,同時也可能引發(fā) ORA-00955 錯誤提示呢,只有把重復(fù)的數(shù)據(jù)刪除掉,再執(zhí)行添加主鍵的 SQL 語句,才有可能順利完成主鍵的修改呀。
解決 ORA-00955 錯誤的方法
檢查重復(fù)對象并處理
當遇到 ORA-00955 錯誤時,首先要做的就是檢查是否存在重復(fù)對象。我們可以通過一些查詢語句來查找與報錯相關(guān)的重復(fù)對象,像是同名的表、約束、索引等等。例如,使用 “select a.OBJECT_type,a.* from all_objects a where upper (a.OBJECT_NAME) ='[具體對象名稱]';” 這樣的語句來進行查詢(這里的 “[具體對象名稱]” 替換為你實際創(chuàng)建時報錯提示重復(fù)的那個名稱哦)。如果通過查詢找到了重復(fù)對象,那就要根據(jù)實際情況來決定是對其進行刪除還是更改名稱等處理辦法啦。要是創(chuàng)建表時報錯,發(fā)現(xiàn)有重復(fù)的視圖或者其他同名稱對象,就可以選擇修改當前要創(chuàng)建對象的名稱,使其具有唯一性,或者刪掉那個與之重名的已有對象。比如創(chuàng)建 “temp_aud” 臨時表時報錯 ORA-00955,查詢發(fā)現(xiàn)有一個視圖和該表重名了,這時就可以把臨時表名稱改掉或者刪除那個重名的視圖來解決問題呢。而如果是在修改主鍵等操作時出現(xiàn)該錯誤,同樣先查詢相關(guān)的主鍵、索引等是否存在重名情況。先通過 “select * from user_cons_conlumns c where c.table_name=‘[表名]’;” 查詢表中的主鍵,確定要刪除的主鍵名稱后,執(zhí)行 “alter table [表名] drop constraint ‘主鍵名稱’” 語句來刪除原主鍵,再查詢是否有同名稱的主鍵索引,若有就用 “drop index [表名].‘主鍵索引名稱’” 語句刪除掉,之后就可以嘗試重新添加主鍵啦??傊?,仔細排查并妥善處理重復(fù)對象是解決 ORA-00955 錯誤的重要一步哦。
調(diào)整命名策略
合理的命名在避免 ORA-00955 錯誤方面起著至關(guān)重要的作用呢。在給數(shù)據(jù)庫中的各類對象命名時,遵循一定的規(guī)則和約定能減少很多不必要的麻煩哦。當給表命名時,典型的命名約定是給它一個描述性的名稱,并且最好總是使它成為單數(shù)冠詞(比如 “customer” 或 “facility” )或復(fù)數(shù)冠詞(比如 “customers” 或 “facilities”)并保持一致呀。對于列命名來說,同樣要賦予它一個描述性的名稱哦。除非受到字符限制,否則盡量不要使用縮寫(要是使用了縮寫,可以在該列上添加注釋來提供完整的詳細信息),而且通常不需要在列名中包括表名,畢竟這屬于多余的信息,不然開發(fā)人員每次使用該列時都得多鍵入額外的字符呢。在命名約束時,也要給它一個能標識其位置和內(nèi)容的描述性名稱哦。這往往涉及到包括約束的類型(因為表的一列可以有多個約束)、表名(由于可能存在多個表且每個表有相同的列名)以及列名(因為在同一個表中,不同的列上可能有多個相同類型的約束)等要素呀。約束名稱常見的公式可能是 “tablename_columnname_(pk|fk|u|nn|chk)” 或 “(pk|fk|u|nn|chk)_tablename_columnname”(具體選擇哪種取決于在搜索約束時是希望將表名還是約束類型作為對約束進行排序的主要標準哦)。不過,無論采用哪種命名約定,都一定要確保在整個數(shù)據(jù)庫中能一致地應(yīng)用它,這樣才能有效避免因命名問題而引發(fā) ORA-00955 錯誤呀。
處理臨時表相關(guān)報錯情況
在處理臨時表出現(xiàn) ORA-00955 錯誤且被鎖等特殊情況時,需要一些針對性的解決步驟哦。比如在執(zhí)行創(chuàng)建臨時表語句,像 “create global temporary table temp_aud on commit preserve rows as select * from sys.dba_audit_trail;” 這樣的語句時報錯 ORA-00955,原因是有一個視圖和該臨時表重名了,那首先要查看重名的對象,通過 “select a.OBJECT_type,a.* from all_objects a where upper (a.OBJECT_NAME) ='[臨時表名稱]';” 語句來查找(這里 “[臨時表名稱]” 替換為實際報錯的臨時表名哦),找到后可以選擇修改臨時表名稱或者刪掉那個重復(fù)的對象呀。但要是在刪除這個臨時表時報錯 ORA-14452(試圖創(chuàng)建、變更或刪除正在使用的臨時表中的索引,意味著這張臨時表被鎖了,有其它 session 正在使用它呢),這時解決辦法就是殺掉正在使用該表的 session 哦。先通過 “select sid,serial# from v lock where id1 =(select object_id from user_objects where object_name=upper (' [臨時表名稱]')));” 語句查找還在使用臨時表的會話(同樣 “[臨時表名稱]” 替換為實際的哦),不過可能因為有多個,需要分步查詢,先查出 “object_id”,再通過 “object_id” 查 “sid”,最后根據(jù) “sid” 查出 “sid” 和 “serial#”,然后執(zhí)行 “alter system kill session'sid,serial#';” 殺掉進程呀。要是殺掉進程后出現(xiàn) ORA-00031(標記要終止的會話,說明在數(shù)據(jù)庫級不能殺掉該死鎖進程),那就需要到操作系統(tǒng)級來處理了哦。利用 “select spid, osuser, s.program from v process p where s.paddr = p.addr and s.sid = [對應(yīng)的 sid 值];” 語句查出這個 session 的 “spid”,接著在數(shù)據(jù)庫服務(wù)器上 kill 掉查出的系統(tǒng)進程,并用 root 用戶下 kill 掉這個進程,之后再去嘗試刪除臨時表等操作,就能解決臨時表相關(guān)的 ORA-00955 錯誤及連帶的一些問題啦。
預(yù)防 ORA-00955 錯誤的小技巧
提前做好對象名稱規(guī)劃
在日常進行數(shù)據(jù)庫操作前,就應(yīng)該對各類要創(chuàng)建的對象名稱有一個整體的規(guī)劃。比如,在開展一個新項目,涉及到多張數(shù)據(jù)表、多個存儲過程等對象創(chuàng)建時,先梳理出一個命名清單,按照一定的規(guī)則來給不同類型的對象命名,避免隨意命名導(dǎo)致后續(xù)出現(xiàn)名稱沖突??梢愿鶕?jù)業(yè)務(wù)模塊來劃分命名范圍,例如涉及用戶模塊的表統(tǒng)一以 “user_” 開頭來命名,這樣能從源頭上減少出現(xiàn) ORA-00955 錯誤的可能性哦。
及時記錄已用名稱
養(yǎng)成一個好習(xí)慣,每當成功創(chuàng)建一個數(shù)據(jù)庫對象后,就將其名稱記錄下來??梢詫iT建立一個文檔或者使用電子表格來記錄,標注好對象類型、創(chuàng)建時間等關(guān)鍵信息。這樣在后續(xù)創(chuàng)建新對象時,就能快速對照查看是否存在重名情況啦。例如,團隊成員 A 創(chuàng)建了名為 “product_info” 的表用于存儲產(chǎn)品基本信息,記錄下來后,其他成員在創(chuàng)建相關(guān)視圖或者存儲過程等對象時,如果要用到類似名稱,就能提前知曉并更換,防止觸發(fā) ORA-00955 錯誤呀。
定期清理無用對象
定期對數(shù)據(jù)庫中那些不再使用的對象進行清理。有些時候,可能之前做測試或者臨時搭建環(huán)境創(chuàng)建了很多對象,后來項目結(jié)束了,這些對象就閑置在數(shù)據(jù)庫里,它們占用了名稱資源,很容易導(dǎo)致后續(xù)創(chuàng)建新對象時出現(xiàn)名稱沖突。像通過 “drop table [表名];” 語句來刪除無用的表,“drop procedure [存儲過程名];” 來清理不再需要的存儲過程等。例如,之前為了測試某個功能創(chuàng)建了一批臨時表,測試結(jié)束后及時用相應(yīng)的刪除語句把它們清理掉,就能避免后續(xù)創(chuàng)建正式表時出現(xiàn)名稱重復(fù)報錯的問題哦。
利用命名規(guī)范工具或插件(如果有)
現(xiàn)在市面上有些數(shù)據(jù)庫管理工具或者開發(fā)工具的插件,具備命名規(guī)范檢查和提示功能哦。在創(chuàng)建對象時,它們可以根據(jù)預(yù)設(shè)的命名規(guī)則來提醒你是否存在潛在的名稱沖突風險。如果所在的開發(fā)團隊使用了這類工具,那一定要充分利用起來呀。比如在某款常用的數(shù)據(jù)庫開發(fā) IDE 中,安裝了對應(yīng)的