为什么Oracle不告诉你哪个表或视图不存在?

如果您使用过Oracle,您可能会收到“ORA-00942:表或视图不存在”的帮助信息。 有没有合法的技术原因,该消息不包括缺less的对象的名称?

有关这个问题的争论是由于TSA制作的安全声音。 如果我是攻击者,我会知道我刚刚尝试利用哪张表,并且能够轻松解释这个无用的消息。 如果我是一个使用多层应用程序代码进行复杂连接的开发人员,通常很难说清楚。

我的猜测是,当这个错误最初实现时,有人忽略了添加对象的名字,现在,人们担心会破坏兼容性来修复它。 (如果parsing错误信息的代码做的愚蠢的事情,如果它改变,将会感到困惑。

是否有开发人员友好的(而不是招聘你的数据库pipe理员)的方式来确定失踪表的名称?


尽pipe我已经接受了与该主题相关的答案,但它并没有真正回答我的问题: 为什么不是错误消息的名称部分? 如果有人能拿出真正的答案,我会很乐意改变我的投票。

您可以在参数文件(纯文本或spfile)中设置EVENT以强制Oracle转储user_dump_dest中的详细跟踪文件,如果不是SQL,则该对象名称可能位于该文件中。

EVENT =“942跟踪名称错误检测级别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语句中缺less的表的名称和行号。

同样,在一行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复制并粘贴到其中一个工具中以提供帮助。 您也可能会发现分析信息也很有用。

我从来没有解释Oracle错误消息的问题。 其中一部分原因是我所见过的用于为Oracle开发SQL的每个交互式工具都有助于指出查询出错的位置。 包括其他人已经注意到的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开始在查询中遇到问题的标记。 在parsing器上做一些工作,你可以编写一个工具来挑出违规的表。

为了回答潜在的问题,Oracle错误似乎并没有按照您期望的方式进行devise。 据我所知,Oracle中的错误信息都不支持variables文本。 相反,Oracle返回两位信息:错误号和发生错误的位置。 如果你有适当的工具,用这些数据来诊断错误是相当容易的。 可以认为,Oracle的系统比创build工具更好,而不是根据错误提供不同数量的诊断数据。 想象一下,必须为Oracle的所有错误消息(包括将来的错误)编写一个自定义parsing器来突出显示违规位置。

有时包括表名会是误导。 只要知道事情出错的地方,可以是一个巨大的帮助:

 SQL> select * from where dummy = 'X'; select * from where dummy = 'X' * ERROR at line 1: ORA-00903: invalid table name 

至于为什么甲骨文select这样做,我有一些猜测:

  1. IBM使用了这种types的System R的错误消息,Larry Ellison,Bob Miner和Ed Oates复制了这个消息来构buildOracle V2。 (向后兼容)

  2. 错误编号和位置是诊断信息的最小可能表示。 (简约)。

  3. 如上所述,为了简化连接到Oracle的工具的创build。 (互操作性)。

无论如何,我不认为你需要成为DBA才能找出哪个表不存在。 你只需要使用适当的工具。 (并且调整你的期望,我想。)

我不同意这个观点,SQL +让你明白哪个表名是不可接受的。 诚然,它有助于直接的DML,虽然parsing它是非常困难的。 但是,当涉及到dynamic时,我们得不到帮助:

 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 

如果不是一个巨大的声明,那么最简单的方法就是检查数据字典,

 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:多语言界面

您的数据库实例有一个特定于语言的消息configuration文件。 消息被拉出并从纯数字版本转换为数字+文本版本。

硬编码string可能被认为是更好的,而不是由于格式不正确的“%s”string而在运行时出现神秘失败的风险。

(我不是特别同意这个POV,顺便说一句)。

原因2:安全

现在,如果您打印一个PHP等,将Oracle错误消息转储到浏览器,则不会特别暴露应用程序的内部工作。

如果在默认情况下打印更多的细节,应用程序会更加暴露…例如,如果花旗银行打印了更多的解释性信息。

(请参阅上面的免责声明,我也很乐意在错误中获得更多信息。)

@马修

您的查询是一个开始,但是当您有多个模式时,它可能不起作用。 例如,如果我以自己的身份login到我们的实例,则可以读取所有表格。 但是,如果我没有使用模式来限定表名,那么对于没有同义词的表,我将得到一个ORA-00942:

 SQL> select * from tools; 
从工具中select* 
               * 
第1行的错误: 
 ORA-00942:表或视图不存在 

尽pipe如此,表格仍然显示在all_tables中:

 SQL> select all,table_name from all_tables where table_name ='TOOLS'; 

 OWNER TABLE_NAME 
 ------------------------------ -------------------- ---------- 
应用工具 

@erikson对不起,没有多大帮助。 我与马克 – 我用了TOAD。