zoukankan      html  css  js  c++  java
  • oracle中执行execute的时候报异常ORA-01031的解决办法

    在做实验的时候,编写关于“在存储过程中使用动态sql,建立一个统计表,并把统计结果,插入这个表中”的PL/sql语句在执行时出现权限不足的问题。



    上网查询很多,看到了下面这篇博文(解决了我的问题)

    两种解决办法

    • 在编写存储过程时加上authid current_user
    • 通过sys用户显式进行系统权限grant create table to hr(相应的用户名);


    转载来的博文:

    create or replace procedure p_create_table

        Authid Current_User is
        begin
        Execute Immediate 'create table create_table(id int)';
        end p_create_table;
    红色字体为关键  使用户可以使用权限执行execute
     
    我们知道,用户拥有的role权限在存储过程是不可用的。遇到这种情况,我们一般需要显式进行系统权限,如grant create table to suk;但这种方法太麻烦,有时候可能需要进行非常多的授权才能执行存储过程,实际上,oracle给我们提供了在存储过程中使用role权限的方法:修改存储过程,加入Authid Current_User时存储过程可以使用role权限。
    我们知道,用户拥有的role权限在存储过程是不可用的。如:
        SQL> select * from dba_role_privs where grantee='SUK';
        GRANTEE GRANTED_ROLE ADMIN_OPTION DEFAULT_ROLE
        ------------ ------------ ------------ ------------
        SUK DBA NO YES
        SUK CONNECT NO YES

        SUK RESOURCE NO YES


    用户SUK拥有DBA这个role

    再创建一个测试存储过程:    

    create or replace procedure p_create_table  is

    begin

    Execute Immediate 'create table create_table(id int)';
    end p_create_table;


    然后测试
        SQL>
    begin  p_create_table;  end;
        ORA-01031: 权限不足
        ORA-06512: 在"SUK.P_CREATE_TABLE", line 3

        ORA-06512: 在line 1


    可以看到,即使拥有DBA role,也不能创建表。role在存储过程中不可用。遇到这种情况,我们一般需要显式进行系统权限,如grant create table to suk;


    但这种方法太麻烦,有时候可能需要进行非常多的授权才能执行存储过程。实际上,oracle给我们提供了在存储过程中使用role权限的方法:
    修改存储过程,加入Authid Current_User时存储过程可以使用role权限。
        create or replace procedure p_create_table
        Authid Current_User is
        begin
        Execute Immediate 'create table create_table(id int)';
        end p_create_table;


    再尝试执行:

        SQL> exec p_create_table;
        PL/SQL procedure successfully completed


    已经可以执行了。

    ==================================================================================
    存储过程默认是用定义者definer 的身份调用的,如果加上AUTHID CURRENT_USER,则用当前登陆的用户权限调用,如果该过程的调用者(而非定义者)被授与系统权限execute any procedure或是被该过程的定义者grant execute on授权的话,不用这个AUTHID CURRENT_USER子句,调用者照样可以使用这个过程。

    另外,在Oracle的存儲過程中,如果涉及到操作不同schema下的對象的時候,可以在不同的schema下寫相同的procedure,但這樣帶來的問題是維護和同步帶來了麻煩,可以在procedure中加上authid current_user,來說明procedure中操作的對象是當前連接用戶的對象而并不是procedure所屬用戶下的對象。

    -- USER01
    USER01@HUIYI>create table t
    2 (
    3 col1 varchar2(10)
    4 )
    5 /
    
    Table created.
    
    USER01@HUIYI>insert into t values(user);
    
    1 row created.
    
    USER01@HUIYI>commit;
    
    Commit complete.
    
    USER01@HUIYI>select * from t;
    
    COL1
    --------------------
    USER01
    
    -- USER02
    USER02@HUIYI>create table t
    2 (
    3 col1 varchar2(10)
    4 )
    5 /
    
    Table created.
    
    USER02@HUIYI>insert into t values(user);
    
    1 row created.
    
    USER02@HUIYI>commit;
    
    Commit complete.
    
    USER02@HUIYI>select * from t;
    
    COL1
    --------------------
    USER02
    
    USER02@HUIYI>create or replace procedure pro_01
    2 is
    3    l_col1 varchar2(10);
    4 begin
    5    select col1 into l_col1 from t;
    6    dbms_output.put_line(l_col1);
    7 end;
    8 /
    
    Procedure created.
    
    USER02@HUIYI>create or replace procedure pro_02
    2    authid current_user
    3 is
    4    l_col1 varchar2(10);
    5 begin
    6    select col1 into l_col1 from t;
    7    dbms_output.put_line(l_col1);
    8 end;
    9 /
    
    Procedure created.
    
    USER02@HUIYI>grant all on pro_01 to public;
    
    Grant succeeded.
    
    USER02@HUIYI>grant all on pro_02 to public;
    
    Grant succeeded.
    
    USER02@HUIYI>call pro_01();
    USER02
    
    Call completed.
    
    USER02@HUIYI>call pro_02();
    USER02
    
    Call completed.
    
    -- USER01
    USER01@HUIYI>select * from t;
    
    COL1
    --------------------
    USER01
    
    USER01@HUIYI>call user02.pro_01();
    USER02
    
    Call completed.
    
    USER01@HUIYI>call user02.pro_02();
    USER01
    
    Call completed.




    【附:一文一图】


  • 相关阅读:
    阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_5_InvalidClassException异常_原理
    阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_4_transient关键字_瞬态关键字
    阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_3_对象的反序列化流_ObjectInputStream
    阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_09 序列化流_2_对象的序列化流_ObjectOutputStream
    阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_08 转换流_5_InputStreamReader介绍&代码实现
    Linux启动流程
    静态库和动态库的区别
    uboot各种目录下的文件作用
    编译选项含义
    C++转换构造函数与类型转换构造函数
  • 原文地址:https://www.cnblogs.com/zhouie/p/8955803.html
Copyright © 2011-2022 走看看