• 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;
     
     
     
  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/yelisen2011/p/4876073.html
Copyright © 2020-2023  润新知