[英]Why doesn't Oracle tell you WHICH table or view does not exist?
如果你使用過Oracle,你可能會收到有用的消息“ORA-00942:表或視圖不存在”。 是否有合法的技術原因消息不包含丟失對象的名稱?
關於這一點的爭論是由於安全聽起來像是由TSA制作的。 如果我是攻擊者,我會知道我剛試圖利用哪個表,並且能夠輕松地解釋這個無用的消息。 如果我是通過多層應用程序代碼處理復雜連接的開發人員,那么通常很難說。
我的猜測是,當最初實現此錯誤時,有人忽略了添加對象名稱,現在,人們擔心它會破壞兼容性來修復它。 (代碼執行愚蠢的事情,如解析錯誤消息,如果它發生變化將會混淆。)
是否有開發人員友好(而不是招募您的DBA)方式來確定缺失表的名稱?
雖然我已經接受了與該主題相關的答案,但它並沒有真正回答我的問題: 為什么這個名稱不是錯誤信息的一部分? 如果有人能提出真正的答案,我會很樂意改變我的投票。
您可以在參數文件(純文本或spfile)中設置EVENT以強制Oracle在user_dump_dest中轉儲詳細的跟蹤文件,對象名稱可能在那里,如果不是SQL應該在那里。
EVENT =“942跟蹤名稱errorstack level 12”
如果您使用的是純文本文件,則需要將所有EVENT設置保留在連續的行中。 不確定如何應用於spfile。
SQL * Plus會告訴您不存在的表。 例如:
SQL> select
2 *
3 from
4 user_tables a,
5 non_existent_table b
6 where
7 a.table_name = b.table_name;
non_existent_table b
*
ERROR at line 5:
ORA-00942: table or view does not exist
這里顯示了缺失表的名稱以及發生錯誤的SQL語句中的行號。
同樣,在單行SQL語句中,您可以看到突出顯示未知表名稱的星號:
SQL> select * from user_tables a, non_existent_table b where a.table_name = b.table_name;
select * from user_tables a, non_existent_table b where a.table_name = b.table_name
*
ERROR at line 1:
ORA-00942: table or view does not exist
就你的問題而言,我猜錯誤消息不包括表名的原因是錯誤消息本身需要是靜態文本。 錯誤行中的行號和位置顯然會傳回SQL * Plus(不知何故)。
如果您使用的是TOAD或TORA等SQL瀏覽工具,它會通過突出顯示或指向將光標移動到您出錯的位置來幫助您解決ORA錯誤。
將SQL復制並粘貼到其中一個工具中以提供幫助。 您也可以找到可用的分析信息。
我不同意這個觀點,即SQL +可以讓你了解哪個表名是不可接受的。 沒錯,它有助於直接DML,雖然解析它非常困難。 但是當談到動態時,我們沒有得到任何幫助:
SQL> begin
2 execute immediate 'insert into blabla values(1)';
3 end;
4 /
begin
*
ERROR at line 1:
ORA-00942: table or view does not exist
ORA-06512: at line 2
我從未遇到過解釋Oracle錯誤消息的問題。 部分原因是我見過的用於開發SQL for Oracle的每個交互式工具都有助於指出查詢出錯的位置。 這包括SQL * Plus,正如其他人所說,以及Perl DBI模塊:
$ exec_sql.pl 'select * from daul'
DBD::Oracle::db prepare failed: ORA-00942: table or view does not exist (DBD ERROR: error possibly near <*> indicator at char 14 in 'select * from <*>daul') [for Statement "select * from daul"] at exec_sql.pl line 68.
嗯,這是一個有點難以閱讀,因為這一切都壓扁在一行。 但是GUI工具可以指向Oracle開始遇到查詢問題的令牌。 並且在解析器上做了一些工作,你可以編寫一個工具來挑選出有問題的表。
為了回答基本問題,Oracle錯誤似乎並不像您期望的那樣工作。 據我所知,Oracle中的錯誤消息都不支持變量文本。 相反,Oracle返回兩位信息:錯誤號和發生錯誤的位置。 如果您有合適的工具,那么使用這些數據來診斷錯誤非常容易。 可以說Oracle的系統比工具創建者更好,而不是根據錯誤提供可變數量的診斷數據。 想象一下,必須為所有Oracle的錯誤消息(包括將來的錯誤)編寫自定義解析器,以突出顯示有問題的位置。
有時包括表名會有誤導性。 只知道出了什么問題可能是一個巨大的幫助:
SQL> select * from where dummy = 'X';
select * from where dummy = 'X'
*
ERROR at line 1:
ORA-00903: invalid table name
至於Oracle選擇以這種方式做事的原因,我有一些猜測:
IBM在System R中使用了這種錯誤消息,Larry Ellison,Bob Miner和Ed Oates復制了這些消息來構建Oracle V2。 (向后兼容性。)
錯誤編號和位置是診斷信息的最小可能表示。 (簡約)。
如上所述,為了簡化連接到Oracle的工具的創建。 (互操作性)。
無論如何,我認為您不需要成為DBA來確定哪個表不存在。 你只需要使用適當的工具。 (並且我想,調整你的期望。)
如果它不是一個巨大的聲明,那么最簡單的方法就是檢查數據字典,
SQL> select * from xx,abc;
select * from xx,abc
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select owner,table_name from all_tables where table_name in ('XX','ABC');
OWNER TABLE_NAME
------------------------------ ------------------------------
MWATSON XX
SQL>
這不是理想的,但缺少去檢查跟蹤文件,我不知道怎么做。
原因1:多語言界面
您的數據庫實例有一個特定於語言的消息配置文件。 消息被拉出並從純數字版本轉換為數字+文本版本。
擁有硬編碼字符串可能被認為比在運行時因為格式不正確的“%s”字符串而導致出現神秘故障的風險更大。
(不是說我特別同意這個POV,順便說一下。)
原因2:安全
現在,如果您打印PHP等,將Oracle錯誤消息轉儲到瀏覽器,則不會特別公開應用程序的內部工作方式。
如果默認打印更多細節,應用程序將更加暴露...例如,如果citibank打印了更多解釋性消息。
(請參閱上面的免責聲明,我也很樂意在錯誤中獲得更多信息。)
@馬修
您的查詢是一個開始,但是當您有多個模式時它可能不起作用。 例如,如果我以自己的身份登錄我們的實例,我可以讀取所有表的訪問權限。 但是,如果我沒有使用模式限定表名,我將為沒有同義詞的表獲得ORA-00942:
SQL> select * from tools; select * from tools * ERROR at line 1: ORA-00942: table or view does not exist
該表仍顯示在all_tables中:
SQL> select owner, table_name from all_tables where table_name = 'TOOLS'; OWNER TABLE_NAME ------------------------------ ------------------------------ APPLICATION TOOLS
@erikson對不起,這沒什么用。 我和馬克一起 - 我用過TOAD。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.