如何使用 Oracle 廉价地验证另一个模式中的表中是不是存在列?
Posted
技术标签:
【中文标题】如何使用 Oracle 廉价地验证另一个模式中的表中是不是存在列?【英文标题】:How does one cheaply validate the existance of a column in a table in another schema with Oracle?如何使用 Oracle 廉价地验证另一个模式中的表中是否存在列? 【发布时间】:2009-10-29 22:20:17 【问题描述】:环境是 Oracle 9 & 10。我没有 DBA 级别的访问权限。
问题是验证特定列是否存在于特定表中,在另一个模式中。
有两种情况需要处理。
-
同一实例中的另一个架构
不同实例中的架构,使用 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,所以我认为它工作是合理的,因为它有效地登录到另一个架构,这应该使视图可以访问。
在 Google 上四处搜索,并在 Oracle 文档的山上耗尽了我的眼球, 我正在寻找可以为我指明正确方向的人,或者至少指出我所缺少的。
有哪些技术可用于从同一实例的架构中获取与用户表相关的元数据,以验证特定列是否存在?
提前致谢。
邪恶。
+1 以获得好的答案。 谢谢。
【问题讨论】:
【参考方案1】:您可以使用以下查询:
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 权限),那么您将知道该列是否存在。如果您对桌子没有任何权利,您将无法获得有关该桌子的元信息。
【讨论】:
您还可以查询 DBA_TAB_COLS。如果您有权访问该表,则无论您是否能够查询该表中的数据,都可以查看有关其他对象的信息。如果您希望允许管理员帐户检查 EMP 表中是否存在 SALARY 列,而无需访问该列中的数据,这将非常有用。【参考方案2】:与其他回复一样,通常我使用 ALL_TAB_COLUMNS 进行这样的查询。但这只会显示您有 SELECT 的表中的列。它是在该列上选择的——万一他们为该表实现了列级权限,您可能能够看到该表,但看不到感兴趣的特定列。对于我们大多数人来说,这是极其罕见的。
DBA_TAB_COLUMNS 将显示所有列,但您需要选择 DBA 授予您的架构的列。 (实际上,您需要获得 ALL_TAB_COLUMNS 的授权才能使用它,但这在大多数商店中很常见)。也可以使用 DBMS_METADATA PL/SQL 内置包,具有类似的限制,但我认为您会发现它更复杂。
当然,您也可以尝试从 barney.some_table.some_column@my_dblink(或您感兴趣的任何部分)中选择一条记录。然后处理异常。丑,大多数情况下不推荐。
【讨论】:
【参考方案3】:您可以使用 all_tab_columns。
但请注意,您只会看到您被允许看到的内容。
【讨论】:
【参考方案4】:相同的实例,不同的架构:
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';
【讨论】:
以上是关于如何使用 Oracle 廉价地验证另一个模式中的表中是不是存在列?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用expdp和impdp命令将一个数据库的表空间导入到另一个数据库中?(oracle 10g)