初试oracle中synonym的使用

本文介绍了一种解决ASP.NET程序因数据库包迁移导致调用失败的方法。通过在原用户下创建指向新位置的同义词,并授予执行权限,实现了不修改应用程序即可解决问题的目的。

数据中心有TA和VM两个用户,原来TA底下有一个Package,名叫pckg_dw_cust_query,在asp.net应用程序中都是通过ta.pckg_dw_cust_query来调用的,现在由于程序的改动,将这个包移到vm用户下面去了。此时,网站程序中原来调用ta.pckg_dw_cust_query查询数据的页面报错。

对于这个问题,通过创建一个synonym可以完美的解决(即asp.net端程序不作任何修改)。在ta用户下建一个与包名同名称的同义词,然后将vm.pkcg_dw_cust_query的execute权限赋给ta用户。这样就解决问题,应用程序不作修改(ta.pkcg_dw_cust_query调用的方式仍旧是正确的)。附sql执行语句如下:

CREATE SYNONYM "TA"."PCKG_DW_CUST_ANALYZE" FOR "VM"."PCKG_DW_CUST_ANALYZE";
GRANT EXECUTE ON "VM"."PCKG_DW_STAT_QUERY" TO "TA";

<think>嗯,用户的问题是关于Oracle数据库中同义词被标记为无效(invalid)但仍然可以查询的原因及解决方法。我需要先回忆一下同义词在Oracle中的工作机制。 首先,同义词分为公有和私有,它们是指向其他对象(比如表、视图、函数等)的别名。当创建同义词时,系统会检查目标对象是否存在。如果目标对象被删除或结构发生改变,比如列被修改或删除,同义词的状态就会变成INVALID。但用户提到即使标记为无效,同义词仍然可以查询,这可能是因为虽然编译时检查到问题,但实际运行时如果权限足够,Oracle仍然会尝试解析。 接下来,可能的原因有几个。权限问题,比如用户有直接访问底层对象的权限,即使同义词无效,仍然可以通过直接访问来查询。另外,同义词的依赖关系可能没有及时更新,导致状态未正确反映。还有可能是延迟失效特性,Oracle可能不会立即将同义词标记为无效,而是在首次访问时检查。 解决方法方面,首先需要重新编译同义词,使用ALTER SYNONYM ... COMPILE命令。如果目标对象结构有变化,可能需要重建同义词。检查用户权限,确保同义词的拥有者有必要的权限。另外,使用数据字典视图如DBA_SYNONYMS来检查同义词的定义是否正确,目标对象是否存在。如果存在延迟失效的情况,可能需要手动干预重新编译或重建。 用户可能没有提到的是,有时候同义词无效可能是因为对象在不同模式下,或者存在同名的公共同义词覆盖了私有同义词。这也是需要检查的地方。另外,Oracle的版本不同可能会有不同的行为,需要确认版本是否有影响。 在生成相关问题的时候,需要涵盖权限管理、同义词失效的其他情况、如何监控同义词状态、依赖对象变更的影响,以及无效同义词对性能的影响。这些扩展问题能帮助用户更全面地理解问题。</think>### Oracle同义词显示无效但仍可查询的原因及解决方法 #### 一、根本原因分析 1. **对象依赖性变化** 当同义词指向的基表、视图或存储过程等底层对象发生结构变更(如列删除、表重命名)时,Oracle会将同义词标记为$STATUS = 'INVALID'$[^1],但已建立的会话可能继续使用原有解析缓存。 2. **权限穿透机制** 即使同义词标记为无效,若用户同时满足以下条件仍可访问: $$ \begin{cases} \text{直接访问权限:} & \text{用户具有基对象的直接SELECT权限} \\ \text{路径有效性:} & \text{基对象物理存在且可访问} \end{cases} $$ 3. **延迟失效特性** Oracle采用惰性失效验证机制,仅在首次访问时检查对象有效性,若此时基对象已恢复可用状态则继续操作。 #### 二、解决方案 ```sql -- 1. 重新编译同义词 ALTER SYNONYM schema.synonym_name COMPILE; -- 2. 验证基对象状态 SELECT owner, object_name, object_type, status FROM dba_objects WHERE object_name = 'BASE_OBJECT_NAME'; -- 3. 重建同义词(当基对象路径变更时) DROP SYNONYM schema.synonym_name; CREATE [PUBLIC] SYNONYM schema.synonym_name FOR schema.base_object@dblink; -- 4. 检查权限穿透问题 REVOKE SELECT ON base_table FROM public; GRANT SELECT ON base_table TO specific_role; ``` #### 三、验证流程图 $$ \begin{array}{ccc} \text{查询同义词} & \rightarrow & \text{检查VALID状态} \\ & \downarrow & \text{Yes} \rightarrow \text{正常访问} \\ & \text{No} & \\ & \downarrow & \\ \text{检查基对象存在性} & \rightarrow & \text{存在} \rightarrow \text{重建/编译} \\ & \downarrow & \\ \text{不存在} & \rightarrow & \text{对象恢复/路径修正} \end{array} $$ [^1]: 引用Oracle官方文档:当依赖对象发生结构性变更时,所有依赖对象会被标记为INVALID状态,但运行时可能通过权限穿透机制继续工作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值