zoukankan      html  css  js  c++  java
  • Oracle存储过程动态创建临时表/存储过程执行权限问题--AUTHID CURRENT_USER

    关于Oracle存储过程执行权限问题的解决

    http://blog.sina.com.cn/s/blog_6ceed3280101hvlo.html

    (2014-04-02 04:06:28)

      分类: oracle-基础
        今天晚上升级,有个存储过程死活编译不过去,提示权限不足,但是用户是具有dba权限的,网上一查才知道,oracle存储过程分两种,DR(Definer's Rights ) Procedure和IR(Invoker's Rights ) Procedure。
        1、定义者权限:定义者权限PL/SQL程序单元是以这个程序单元拥有者的特权来执行它的,也就是说,任何具有这个PL/SQL程序单元执行权的用户都可 以访问程序中的对象。所有具有执行权的用户都有相同的访问权限,在定义者权限下,执行的用户操作的schema为定义者,所操作的对象是定义者在编译时指 定的对象。在定义者(definer)权限下,当前用户的权限为角色无效情况下所拥有的权限。
        2、调用者权限:调用者权限是指当前用户(而不是程序的创建者)执行PL/SQL程序体的权限。这意味着不同的用户对于某个对象具有的权限很可能是不同 的,这个思想的提出,解决了不同用户更新不同表的方法。在调用者权限下,执行的用户操作的schema为当前用户,所操作的对象是当前模式下的对象。在调 用者(invoker)权限下,当前用户的权限为当前所拥有的权限(含角色)。
        3、ORACLE默认为定义者权限,定义者权限在存储过程中ROLE无效,需要显示授权,例如在存储过程中调用其他用户的表,但是定义存储过程的当前用户没有显示访问该表的权限,即使当前用户具有dba角色,编译过程中也会出现权限不足的问题,因为role无效。
        定义存储过程时,通过指定AUTHID 属性,定义DR Procedure 和IR Procedure
    DR Procedure 
    1、定 义
        CREATE OR REPLACE procedure DEMO(ID in NUMBER) AUTHID DEFINER as
          ...
        BEGIN
          ...
        END DEMO;
    IR Procedure
    1、定 义
        CREATE OR REPLACE procedure DEMO(ID in NUMBER) AUTHID CURRENT_USER as
         ...
        BEGIN
         ...
        END DEMO;
     

    用存储过程创建数据表:

    创建时注意必须添加authid current_user ,如果创建的表已存在,存储过程继续执行,但如不不加此关键语句,存储过程将出现异常,

    这个语句相当于赋权限。
     
    我的实例:SP1 call SP 2:
    1. SP1:
    CREATE OR REPLACE Procedure Proc_Update_ID_NO ( v_IN in Varchar2, v_OUT Out Varchar2) AUTHID CURRENT_USER
    As

    v_sqlerrm VARCHAR2(4000) ;
    v_temp_table varchar(30);

    Begin

    -- DELETE DUPLICATE DATA FROM table CAR.ZCXYXX_SZJSPX,KEEP THE LATEST ONE RECORD.
    --CALL SP  Proc_DISTINCT_ZCXYXX_SZJSPX('TEMP_ZCXYXX_SZJSPX')
    v_temp_table:='TEMP_ZCXYXX_SZJSPX';

     -- Call SP to delete duplicate records      
     Proc_DISTINCT_ZCXYXX_SZJSPX(v_temp_table);
        
     
      MERGE INTO DRIVER_TRAIN_LOG Target USING
      (
            SELECT DISTINCT
                   DRIVER_NO               ,--学员流水号
                   ID_NO                   ,--身份证明号码
                   TRAIN_CAR_CLASS          --申请车型(准驾车型
            FROM  ZCXYXX_SZJSPX
      ) Source
      ON
      (
           Source.DRIVER_NO       = Target.DRIVER_NO     --  AND
          -- Source.TRAIN_CAR_CLASS = Target.TRAIN_CAR_CLASS
      )
      WHEN MATCHED THEN  UPDATE  SET
                   Target.ID_NO      = Source.ID_NO ;
                   --Target.TRAIN_CAR_CLASS = Source.TRAIN_CAR_CLASS ;

       COMMIT;  --1
       
       /* UPDATE TRAIN_CAR_CLASS */
        MERGE INTO ZCXYXX_SZJSPX Target USING
        (
              SELECT DISTINCT
                     ID_NO                   ,--身份证明号码
                     TRAIN_CAR_CLASS          --申请车型(准驾车型
              FROM  DRIVER_TRAIN_LOG
        ) Source
        ON
        (
             Source.ID_NO      = Target.ID_NO
        )
        WHEN MATCHED THEN  UPDATE  SET
                     Target.TRAIN_CAR_CLASS      = Source.TRAIN_CAR_CLASS ;

       COMMIT;

       EXCEPTION
       WHEN OTHERS THEN
            v_sqlerrm := sqlcode|| SQLERRM|| '存储过程[Proc_Update_ID_NO]执行失败!';
            RAISE_APPLICATION_ERROR(-20003,v_sqlerrm);

       ROLLBACK;


       v_OUT := v_sqlerrm ;

    End Proc_Update_ID_NO;
     
    ----------------------
    SP2:
    create or replace procedure Proc_DISTINCT_ZCXYXX_SZJSPX(IN_TABLE_NAME varchar2) AUTHID CURRENT_USER  as
      /*********************************
    名称:Proc_DISTINCT_ZCXYXX_SZJSPX
    功能描述:创建临时数据存储表

    修订记录:
    版本号   编辑时间  编辑人  修改描述
    1.0.0    2015-9-20  **  1.创建此存储过程
    1.0.1    2015-9-21  **  2.修改表名称及变量名称,增加必要注释

    存储过程执行权限问题: AUTHID CURRENT_USER

    入参出参描述:
    IN_TABLE_NAME 要创建的临时表名
    **********************************/
          v_tablename varchar2(30);--表名
          v_flag number(10,0);
          v_sqlfalg varchar(200);
          v_create_sql varchar(4000);
    begin
          v_flag:=0;
          v_tablename:=UPPER(IN_TABLE_NAME);
          v_sqlfalg:='select count(*) from user_TABLES where table_name='''||v_tablename||'''';
          v_create_sql:='CREATE TABLE '|| v_tablename ||' AS SELECT * from
    (  select DRIVER_NO,ID_NO,NAME,TRAIN_CAR_CLASS,ACCEPT_DATE,REGIST_STATUS,OPERATION, rec_update_date,MEMO,
       row_number() over (partition BY ID_NO order by rec_update_date desc) RN from ZCXYXX_SZJSPX WHERE RN=1)' ;
         -- dbms_output.put_line(v_create_sql);
          
          execute immediate v_sqlfalg into v_flag;
          if v_flag=0 then  --如果没有这个表 则去创建
            begin
                -- DELETE DUPLICATE DATA FROM table CAR.ZCXYXX_SZJSPX,KEEP THE LATEST ONE RECORD.
                execute immediate v_create_sql;
                execute immediate 'DROP TABLE ZCXYXX_SZJSPX';
                execute immediate 'ALTER TABLE TEMP_ZCXYXX_SZJSPX rename TO ZCXYXX_SZJSPX';
             end;
           else
             execute immediate 'DROP TABLE TEMP_ZCXYXX_SZJSPX';
                -- DELETE DUPLICATE DATA FROM table CAR.ZCXYXX_SZJSPX,KEEP THE LATEST ONE RECORD.
                execute immediate v_create_sql;
                execute immediate 'DROP TABLE ZCXYXX_SZJSPX';
                execute immediate 'ALTER TABLE TEMP_ZCXYXX_SZJSPX rename TO ZCXYXX_SZJSPX';
          end if;


       EXCEPTION
       WHEN OTHERS THEN
            --dbms_output.put_line( SQLCODE|| ' :'|| SQLERRM);
            RAISE_APPLICATION_ERROR(-20003,SQLCODE|| SQLERRM|| '存储过程[Proc_DISTINCT_ZCXYXX_SZJSPX]执行失败');
       ROLLBACK;
    end;
     
     
     
  • 相关阅读:
    Python 爬虫的工具列表
    使用rabbitmq手动确认消息的,定时获取队列消息实现
    redis订阅发布简单实现
    ubuntu下打开html页面
    关系数据库基本术语
    事务的基本概念,附图示
    oracle 一对多数据分页查询筛选
    一个在linux环境执行io操作的bug
    再springMVC中自定义文件上传处理解决与原spring中MultipartResolve冲突问题
    oracle存储过程删除树状结构的表数据
  • 原文地址:https://www.cnblogs.com/yelisen2011/p/4876073.html
Copyright © 2011-2022 走看看