最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

关于procedure中调用dbms_lock的package

[复制链接]
跳转到指定楼层
楼主
发表于 2014-8-13 15:25:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 dbaxiaoyu 于 2014-8-13 15:51 编辑

开发人员创建的procedure需要调用dbms_lock的package中的对象,调用时候出现了类似下列的问题。

[AppleScript] 纯文本查看 复制代码
SQL> create or replace procedure proc01 as
2 begin
3 dbms_lock.sleep(10);
4 end;
5 /
Procedure created.
SQL> show user;
USER is "SYS"
SQL> conn xiaoyu/xiaoyu
Connected.
SQL> create or replace procedure proc01 as
2 begin
3 dbms_lock.sleep(10);
4 end;
5 /
Warning: Procedure created with compilation errors.
SQL> show errors;
Errors for PROCEDURE PROC01:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1 PL/SQL: Statement ignored
3/1 PLS-00201: identifier 'DBMS_LOCK' must be declared
SQL> conn / as sysdba
Connected.


这里用静态sql调用dbms_lock的package时,Oracle报出了无法识别该package,这里需要单独授权这个package给用户,这个需要特别注意,因为正常的匿名块程序中我们是可以调用的,但是procedure中则不行了。

[AppleScript] 纯文本查看 复制代码
[/p][p=24, null, left]SQL> grant execute on sys.dbms_lock to xiaoyu;
Grant succeeded.
SQL> conn xiaoyu/xiaoyu
Connected.
SQL> create or replace procedure proc01 as
2 begin
3 dbms_lock.sleep(10);
4 end;
5 /
Procedure created.


但是这里并不是说所有的dbms开头的package下的对象都不能在procedure或者function中调用,比如dbms_stats的package在不单独授权的情况下就能够正常调用。

[AppleScript] 纯文本查看 复制代码
SQL> create or replace procedure proc03 as
2 begin
3 dbms_stats.gather_table_stats(ownname=>'SYS',tabname=>'T_DYNAMIC01');
4 end;
5 /
Procedure created.

这里我们想想动态sql能否实现了:

[AppleScript] 纯文本查看 复制代码
SQL> revoke execute on sys.dbms_lock from xiaoyu;
Revoke succeeded.
SQL> create or replace procedure proc01 as
2 begin
3 execute immediate 'dbms_lock.sleep(10)';
4 end;
5 /
Procedure created.
SQL> exec proc01;
BEGIN proc01; END;
*
ERROR at line 1:
ORA-00900: invalid SQL statement
ORA-06512: at "SYS.PROC01", line 3
ORA-06512: at line 1

这里来看动态sql执行的时候出现了问题,oracle报出了在第三行出现了无效的语句,动态sql相比静态sql可以解决一些静态sql无法实现的问题,比如参数的不确定性造成没办法评估程序的具体操作,再比如在存储过程或者匿名块中实现ddl语句。
如下动态sql解决在procedure中实现ddl的示例:

[AppleScript] 纯文本查看 复制代码
SQL> create or replace procedure proc02 as
2 begin
3 create table t_dynamic01 as select * from dual;
4 end;
5 /
Warning: Procedure created with compilation errors.
SQL> show errors;
Errors for PROCEDURE PROC02:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1 PLS-00103: Encountered the symbol "CREATE" when expecting one of
the following:
begin case declare exit for goto if loop mod null pragma
raise return select update while with 
[url=]<<
close current delete fetch lock insert open rollback
savepoint set sql execute commit forall merge pipe[/url]
[url=]
SQL> create or replace procedure proc02 as
2 begin
3 execute immediate 'create table t_dynamic01 as select * from dual';
4 end;
5 /
Procedure created.
SQL> exec proc02;
PL/SQL procedure successfully completed.
SQL> select * from t_dynamic01;
[/url][url=]
D
-
X
[/url]
楼主热帖
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

沙发
发表于 2014-8-13 19:51:12 | 只看该作者
哇塞,开发。

很有挑战性,加油小鱼!
板凳
发表于 2014-8-20 10:06:14 | 只看该作者
本帖最后由 dbdream 于 2014-8-20 10:10 编辑

这是权限问题,dbms_lock包默认普通用户是没权限调用的,而dbms_stats这个包也不是普通用户什么都能调用的,之所以普通用户可以调用这个包,是因为这个包不但可以收集数据库级别的统计信息,还可以收集用户和表级别的,那么用户收集自己的统计信息也就是理所当然的了。
看下面的测试
SQL> conn / as sysdba
Connected.
SQL> drop user dbdream cascade;

User dropped.
SQL> grant connect,resource to dbdream identified by dbdream;

Grant succeeded.

SQL> conn dbdream/dbdream
Connected.
SQL> desc dbms_lock
ERROR:
ORA-04043: object "SYS"."DBMS_LOCK" does not exist
desc描述dbms_stats就可以,日志太多这就不贴了,这个普通用户使用这个包收集用户级的统计信息是可以的,收集数据库级就没权限了。
SQL> exec dbms_stats.gather_database_stats();
BEGIN dbms_stats.gather_database_stats(); END;

*
ERROR at line 1:
ORA-20000: Insufficient privileges to analyze an object in Database
ORA-06512: at "SYS.DBMS_STATS", line 13197
ORA-06512: at "SYS.DBMS_STATS", line 13556
ORA-06512: at "SYS.DBMS_STATS", line 13700
ORA-06512: at "SYS.DBMS_STATS", line 13664
ORA-06512: at line 1
其他用户也是可以的,因为是对dbms_STATS.GATHER_SCHEMA_STATS有权限,但是表级的统计信息,就只能收集自己的,别人的表他没权限。
SQL>  exec dbms_stats.gather_table_stats('DBDREAM','T_TEST');

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats('STREAM','T_TEST');
BEGIN dbms_stats.gather_table_stats('STREAM','T_TEST'); END;

*
ERROR at line 1:
ORA-20000: Unable to analyze TABLE "STREAM"."T_TEST", insufficient privileges
or does not exist
ORA-06512: at "SYS.DBMS_STATS", line 13046
ORA-06512: at "SYS.DBMS_STATS", line 13076
ORA-06512: at line 1
也就是说,如果想用普通用户去收集其他用户下面的表的统计信息,使用schema级的是可以的。
我只是简要测试下,具体细节大家可以自己测试下
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-4-29 08:21

Powered by BI168大数据社区

© 2012-2014 168大数据

快速回复 返回顶部 返回列表