簡體   English   中英

為什么Oracle不告訴您哪個表或視圖不存在?

[英]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選擇以這種方式做事的原因,我有一些猜測:

  1. IBM在System R中使用了這種錯誤消息,Larry Ellison,Bob Miner和Ed Oates復制了這些消息來構建Oracle V2。 (向后兼容性。)

  2. 錯誤編號和位置是診斷信息的最小可能表示。 (簡約)。

  3. 如上所述,為了簡化連接到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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM