1

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

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

有两种情况需要处理。

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

给定我的模式 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/password,所以对我来说它工作似乎是合理的,因为它有效地登录到另一个模式,这应该使视图可以访问。

在谷歌搜索之后,我的眼球在 Oracle doc 的山上疲惫不堪,我正在寻找有人指出我正确的方向,或者至少指出我错过了什么。

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

提前致谢。

邪恶的。

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

4

4 回答 4

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_couns 上的视图,where owner = <Current User>并附有一个)

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

于 2009-10-29T22:46:04.293 回答
2

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

DBA_TAB_COLUMNS 将显示所有列,但您需要选择 DBA 授予您的模式的选项。(实际上,您需要获得 ALL_TAB_COLUMNS 的授权才能使用它,但这在大多数商店中很常见)。也可以使用 DBMS_METADATA PL/SQL 内置包,具有类似的限制,但我认为您会发现它更复杂。

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

于 2009-10-30T13:57:14.493 回答
1

为此,您将使用 all_tab_columns。

但请注意,您只会看到您被允许看到的内容。

于 2009-10-29T22:22:49.830 回答
1

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

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

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

跨数据库链接,与您连接的架构相同:

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';
于 2009-10-30T09:17:40.230 回答