Oracle动态创建序列和触发器生成键

简介:
/***
[email=*@PARAM]*@PARAM[/email] STNAME 不要创建序列的表,多个表则以“,”隔开
**/
CREATE OR REPLACE PROCEDURE PROC_CREATE_SEQ_TRIG(STNAME IN VARCHAR2)
AS
 STRSQL VARCHAR2(4000);
 TABLENAME VARCHAR2(50);
 PID VARCHAR2(50);
 PIDTYPE VARCHAR2(50);
 MAX_ID NUMBER(20);
 CNT NUMBER(20);
 CURSOR CUR IS 
   SELECT TABLE_NAME FROM USER_TABLES;
BEGIN
   --创建HIBERNATE 专用序列
   SELECT COUNT(*) INTO CNT FROM USER_SEQUENCES T WHERE T.SEQUENCE_NAME =  'HIBERNATE_SEQUENCE';
   IF (CNT = 0) THEN
      STRSQL := 'CREATE SEQUENCE HIBERNATE_SEQUENCE INCREMENT BY 1 START WITH 1 ORDER MAXVALUE 999999999999999 CYCLE CACHE 10';
      EXECUTE IMMEDIATE STRSQL;
   END IF;
   OPEN CUR;
        LOOP        
          FETCH CUR INTO TABLENAME;    
                --判断当前表是否需要创建序列
                SELECT INSTR(UPPER(STNAME),TABLENAME) INTO CNT FROM DUAL;               
                IF(CNT = 0) THEN             
                    --判断当前表是否存在主键     
                    SELECT COUNT(*) INTO CNT FROM USER_CONS_COLUMNS WHERE CONSTRAINT_NAME  = (SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS
                    WHERE TABLE_NAME = TABLENAME AND CONSTRAINT_TYPE = 'P');
                    IF CNT = 1 THEN
                       --获取当前表的主键名称
                        SELECT COLUMN_NAME INTO PID FROM USER_CONS_COLUMNS WHERE CONSTRAINT_NAME  = (SELECT CONSTRAINT_NAME FROM USER_CONSTRAINTS
                        WHERE TABLE_NAME = TABLENAME AND CONSTRAINT_TYPE = 'P');
                        --获取主键的数据类型
                        SELECT DATA_TYPE INTO PIDTYPE FROM USER_TAB_COLS WHERE TABLE_NAME = TABLENAME AND COLUMN_NAME = PID;
                        IF (PID IS NOT NULL AND PIDTYPE = 'NUMBER') THEN                   
                          --判断当前序列是否存在  
                          SELECT COUNT(*) INTO CNT FROM USER_SEQUENCES T WHERE T.SEQUENCE_NAME =  'SEQ_' || TABLENAME;
                          IF (CNT = 0) THEN
                            --获取当前表主键的最大值
                            STRSQL := 'SELECT MAX('|| PID ||') FROM '|| TABLENAME;                     
                            EXECUTE IMMEDIATE STRSQL INTO MAX_ID;
                            IF MAX_ID IS NULL THEN
                               MAX_ID := 1;
                            ELSE 
                               MAX_ID := MAX_ID + 1;
                            END IF;     
                            --根据最大值创建序列                                     
                            STRSQL := 'CREATE SEQUENCE SEQ_' || TABLENAME || ' INCREMENT BY 1 START WITH ' || MAX_ID || ' NOMAXVALUE NOCYCLE CACHE 10'; 
                            DBMS_OUTPUT.put_line(STRSQL);                    
                            EXECUTE IMMEDIATE STRSQL;
                            --创建触发器
                            STRSQL := 'CREATE OR REPLACE TRIGGER TRIG_' || TABLENAME || ' BEFORE INSERT ON '|| TABLENAME ||' FOR EACH ROW BEGIN IF INSERTING THEN 
                                      SELECT SEQ_' || TABLENAME || '.NEXTVAL INTO :NEW.' || PID || ' FROM DUAL; END IF; END;';                      
                            EXECUTE IMMEDIATE STRSQL;
                          END IF;
                        END IF;                            
                     END IF;
                 ELSE
                     --判断当前序列或触发器是否存在,如果存在则删除
                     SELECT COUNT(*) INTO CNT FROM USER_SEQUENCES T WHERE T.SEQUENCE_NAME =  'SEQ_' || TABLENAME;
                     IF (CNT > 0) THEN
                        STRSQL := 'DROP SEQUENCE SEQ_' || TABLENAME;
                        EXECUTE IMMEDIATE STRSQL;
                     END IF;
                     SELECT COUNT(*) INTO CNT FROM USER_TRIGGERS T WHERE T.TRIGGER_NAME = 'TRIG_' || TABLENAME;
                     IF (CNT > 0) THEN
                        STRSQL := 'DROP TRIGGER TRIG_' || TABLENAME;
                        EXECUTE IMMEDIATE STRSQL;
                     END IF;                     
                 END IF;
          EXIT WHEN CUR%NOTFOUND;
        END LOOP;    
     CLOSE CUR;    
END PROC_CREATE_SEQ_TRIG;
/
--为当前用户授予动态创建序列和触发器的权限
CONN [email=SYS/ORCL@ORCL]SYS/ORCL@ORCL[/email] AS SYSDBA;
GRANT CREATE ANY SEQUENCE TO ESTATE_TM;
GRANT CREATE ANY TRIGGER TO ESTATE_TM;
CONN [email=ESTATE_TM/ESTATE@ORCL]ESTATE_TM/ESTATE@ORCL[/email];
--创建序列和触发器
DECLARE
    STRFORM VARCHAR2(4000);
BEGIN
    STRFORM := 'DF_AFORM,DF_BIGOPT,DF_CITY,DF_FORM,DF_GRANTRIGHT,DF_HOLIDAY,DF_MENU,DF_PARAMETERS,DF_REPORT,
    DF_RMENU,DF_RREPORT,DF_RRIGHT,DF_SFORM,DF_SMLOPT,DF_UINPUTOPT,DF_UMENU,DF_UREPORT,DF_URIGHT,WF_GRANTRIGHT,
    WF_OMSG,WF_RRIGHT,WF_SFORM,WF_URIGHT';
    PROC_CREATE_SEQ_TRIG(STRFORM);    
END;

/



     本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360597,如需转载请自行联系原作者





相关文章
|
4月前
|
SQL 存储 Oracle
Oracle系列十四:触发器
Oracle系列十四:触发器
|
存储 SQL Oracle
Oracle数据库批量删除表、视图、序列、存储过程、函数脚本
Oracle数据库批量删除表、视图、序列、存储过程、函数脚本
112 0
|
1月前
|
缓存 Oracle 关系型数据库
[oracle]序列
[oracle]序列
|
2月前
|
Oracle 关系型数据库 Java
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
mybatis使用statement.getGenreatedKeys(); useGeneratedKeys=”true”;使用自增主键获取主键值策略和Oracle不支持自增,Oracle使用序列
|
3月前
|
SQL 缓存 Oracle
Oracle中序列Sequence详解
Oracle中序列Sequence详解
|
4月前
|
Oracle 关系型数据库 数据管理
Oracle序列:数据世界的“自动售货机”
【4月更文挑战第19天】Oracle序列是数据库中生成唯一数值的关键工具,比喻为数据世界的“自动售货机”。它提供有序、唯一的序列号,适用于需要唯一标识符的场景,如订单号和员工编号。通过设定起始值、增量和最大值,序列能自动化产生新号码,提高效率并减少错误。然而,使用时需注意设置恰当的属性以适应业务需求,并解决并发访问时的冲突问题。熟练掌握序列使用对数据管理至关重要。
|
10月前
|
索引
Oracle-序列、索引和同义词
Oracle-序列、索引和同义词
44 0
|
4月前
|
缓存 Oracle 关系型数据库
Oracle中的触发器与序列:自增列的魔法组合
【4月更文挑战第19天】Oracle数据库中,通过触发器和序列的组合可实现自增列功能。序列充当自动计数器,提供递增数值,而触发器则在插入新记录时自动分配序列值。创建序列如`CREATE SEQUENCE emp_seq START WITH 1 INCREMENT BY 1 NOCACHE`,然后创建触发器`TRIGGER trg_employees_before_insert`在`BEFORE INSERT`时将序列的下一个值赋予`employee_id`。这种方式使得在插入记录时无需手动设置ID,提高了效率。但使用时需注意序列状态、并发性和性能优化。
|
4月前
|
存储 SQL Oracle
Oracle系列十二:视图、记录、同义词、序列
Oracle系列十二:视图、记录、同义词、序列
|
11月前
|
SQL 存储 Oracle
Oracle触发器----你会教对象触发嘛
Oracle触发器----你会教对象触发嘛