如何用Oracle廉价验证另一个模式中表中列的存在?

时间:2009-10-29 22:20:17

标签: sql oracle ora-00942 database-link

环境是Oracle 9& 10.我没有DBA级别的访问权限。

问题是验证特定表中是否存在特定列,在另一个模式中。

有两种情况需要处理。

  1. 同一实例中的另一个架构
  2. 使用db_link
  3. 在不同实例中的模式

    鉴于我的模式FRED和另一个模式BARNEY,我尝试了类似这样的

    SELECT 1
    FROM BARNEY.USER_TAB_COLS
    WHERE TABLE_NAME = 'SOME_TABLE' 
      AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
    

    产生 [1] :(错误):ORA-00942:表格或视图不存在

    在这一段时间之后,我意识到USER_TAB_COLS,实际上并不是一张桌子。这是一种观点。我一直在从表中选择,但不是从视图中选择。

    我尝试使用db_link做同样的事情,并惊讶地看到数据回来了。 db_link中有一个嵌入式schema_name /密码,所以我认为它有效,因为它有效地登录到另一个模式,这应该使视图可以访问。

    用Google搜索并在Oracle doc山上磨损我的眼球, 我正在寻找有人指出我正确的方向,或者至少指出我缺少的东西。

    有哪些技术可用于从同一实例中的架构获取与用户表相关的元数据,以验证特定列是否存在?

    提前致谢。

    +1获得好的答案。 谢谢。

4 个答案:

答案 0 :(得分:6)

您可以使用以下查询:

SELECT 1
FROM ALL_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE' 
  AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
  AND OWNER = 'BARNEY';

(User_Tables和User_Tab_Cols只是关于all_tables和all_tab_coumns的视图,附加where owner = <Current User>

如果你被允许看到Barney的some_table(即你已被授予至少SELECT权限),那么你就会知道列是否在那里。如果您对该表没有任何权利,您将无法获得有关该信息的元信息。

答案 1 :(得分:2)

与其他回复一样,通常我会将ALL_TAB_COLUMNS用于此类查询。但是这只会显示您拥有SELECT的表中的列。并且它在该列上进行选择 - 万一他们已经为该表实现了列级权限,您可能能够看到该表,但看不到感兴趣的特定列。对于我们大多数人来说,这是非常罕见的。

DBA_TAB_COLUMNS将显示所有列,但您需要选择由DBA授予您的架构的列。 (实际上,你需要在ALL_TAB_COLUMNS上使用它来使用它,但这在大多数商店都很常见)。 DBMS_METADATA PL / SQL内置包也可以使用,但有类似的限制,但我认为你会发现它更复杂。

当然,您也可以尝试从barney.some_table.some_column@my_dblink(或您感兴趣的任何部分)中选择一条记录。然后处理异常。很丑,我不建议在大多数情况下使用它。

答案 2 :(得分:1)

你可以使用all_tab_columns。

但请注意,您只会看到您可以看到的内容。

答案 3 :(得分:1)

相同的实例,不同的架构:

Select Count(*)
From   all_tab_cols
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';

count(*)的优点是始终返回值为1或0的单行,因此您不必处理PL / SQL中的NO_DATA_FOUND错误。

在数据库链接上,与您连接的模式相同的模式:

Select Count(*)
From   user_tab_cols@MY_DB_LINK
Where  table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';

在数据库链接中,与您连接的模式不同的模式为:

Select Count(*)
From   all_tab_cols@MY_DB_LINK
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';