zoukankan      html  css  js  c++  java
  • ORACLE自增长字段实现

    首先,你要有一张表!
          
    Sql代码 复制代码 收藏代码
    1. CREATE TABLE example(   
    2.              ID Number(4) NOT NULL PRIMARY KEY,   
    3.              NAME VARCHAR(25),   
    4.              PHONE VARCHAR(10),   
    5.              ADDRESS VARCHAR(50)   
    6.   
    7.           );  
    CREATE TABLE example(
                 ID Number(4) NOT NULL PRIMARY KEY,
                 NAME VARCHAR(25),
                 PHONE VARCHAR(10),
                 ADDRESS VARCHAR(50)
    
              );


    然后,你需要一个自定义的sequence
        
    Sql代码 复制代码 收藏代码
    1. CREATE SEQUENCE emp_sequence   
    2.           INCREMENT BY 1 -- 每次加几个   
    3.           START WITH 1 -- 从1开始计数   
    4.           NOMAXVALUE -- 不设置最大值   
    5.           NOCYCLE -- 一直累加,不循环   
    6.           NOCACHE -- 不建缓冲区  
    CREATE SEQUENCE emp_sequence
              INCREMENT BY 1 -- 每次加几个
              START WITH 1 -- 从1开始计数
              NOMAXVALUE -- 不设置最大值
              NOCYCLE -- 一直累加,不循环
              NOCACHE -- 不建缓冲区

         以上代码完成了一个序列(sequence)的建立过程,名称为emp_sequence,范围是从1开始到无限大(无限大的程度是由你机器决定的),nocycle 是决定不循环,如果你设置了最大值那么你可以用cycle 会使seq到最大之后循环.对于nocache顺便说一下如果你给出了cache值那么系统将自动读取你的cache值大小个seq
    ,这样在反复操作时会加快运行速度,但如果遭遇意外情况如当机了或oracle死了,则下次取出的seq值将和上次的不连贯.(如果连不连贯无所谓建议用cache,因为时间就是金钱呀!跑题了!)
         书接上文,你只有了表和序列还不够,还需要一个触发器来执行它!代码如下:
        
    Sql代码 复制代码 收藏代码
    1. CREATE TRIGGER "触发器名称" BEFORE   
    2.           INSERT ON example FOR EACH ROW WHEN (new.id is null)   
    3.       begin  
    4.           select emp_sequence.nextval into:new.id from dual;   
    5.        end;  
    CREATE TRIGGER "触发器名称" BEFORE
              INSERT ON example FOR EACH ROW WHEN (new.id is null)
          begin
              select emp_sequence.nextval into:new.id from dual;
           end;

    注意new.id中的id是上面表中的属性字段ID,into:后面不能有空格,另外new.id是表里面真正的属性(字段)名称,而emp_sequence.nextval是建立的序列名称,into:new.id也是表中真正的属性(字段)名称,而在新建序列的时候,那个名称(name)无所谓,但到最后是通过触发器和表绑定到一起的,所以一定要注意!
         打完收工!下面你就试试插入数据吧!
           
    Sql代码 复制代码 收藏代码
    1. INSERT INTO example(Name,phone,address) Values('Cao','56498543','Heibei');  
      INSERT INTO example(Name,phone,address) Values('Cao','56498543','Heibei');

    =============================================================
         ORACLE SEQUENCE的简单介绍(自增长字段)- -

         在oracle中sequence就是所谓的序列号,每次取的时候它会自动增加,一般用在需要按序列号排序的地方。
         1、Create Sequence
              你首先要有CREATE SEQUENCE或者CREATE ANYSEQUENCE权限,
                 
    Sql代码 复制代码 收藏代码
    1. CREATE SEQUENCE emp_sequence   
    2.                    INCREMENT BY 1--每次加几个   
    3.               STARTWITH 1--从1开始计数   
    4.               NOMAXVALUE--不设置最大值   
    5.               NOCYCLE--一直累加,不循环   
    6.               CACHE10;  
     CREATE SEQUENCE emp_sequence
                        INCREMENT BY 1--每次加几个
                   STARTWITH 1--从1开始计数
                   NOMAXVALUE--不设置最大值
                   NOCYCLE--一直累加,不循环
                   CACHE10;


         一旦定义了emp_sequence,你就可以用CURRVAL,NEXTVAL
         CURRVAL=返回sequence的当前值
         NEXTVAL=增加sequence的值,然后返回sequence值
         比如:
              emp_sequence.CURRVAL
              emp_sequence.NEXTVAL

         可以使用sequence的地方:
         -不包含子查询、snapshot、VIEW的SELECT语句
         -INSERT语句的子查询中
         -NSERT语句的VALUES中
         -UPDATE的SET中

         可以看如下例子:
       
    Sql代码 复制代码 收藏代码
    1. INSERT INTO emp VALUES  
    2.          (empseq.nextval,'LEWIS','CLERK',7902,SYSDATE,1200,NULL,20);   
    3.   
    4.          SELECT empseq.currval FROM DUAL;  
     INSERT INTO emp VALUES
              (empseq.nextval,'LEWIS','CLERK',7902,SYSDATE,1200,NULL,20);
    
              SELECT empseq.currval FROM DUAL;


         但是要注意的是:
         第一次NEXTVAL返回的是初始值;随后的NEXTVAL会自动增加你定义的INCREMENTBY值,然后返回增加后的值。CURRVAL 总是返回当前SEQUENCE的值,但是在第一次NEXTVAL初始化之后才能使用CURRVAL,否则会出错。一次NEXTVAL会增加一次 SEQUENCE的值,所以如果你在同一个语句里面使用多个NEXTVAL,其值就是不一样的。明白?

         如果指定CACHE值,ORACLE就可以预先在内存里面放置一些sequence,这样存取的快些。cache里面的取完后,oracle自动再取一组到cache。使用cache或许会跳号,比如数据库突然不正常down掉(shutdownabort),cache中的 sequence就会丢失.所以可以在createsequence的时候用nocache防止这种情况。

         2、Alter Sequence
         你或者是该sequence的owner,或者有ALTE RANYSEQUENCE权限才能改动sequence.可以alter除start至以外的所有sequence参数.如果想要改变start值,必须 drop sequence再re-create.
         Alter sequence的例子
           
    Sql代码 复制代码 收藏代码
    1. ALTER SEQUENCE emp_sequence   
    2.              INCREMENT BY 10   
    3.              MAXVALUE 10000   
    4.         CYCLE--到10000后从头开始   
    5.         NOCACHE;  
      ALTER SEQUENCE emp_sequence
                   INCREMENT BY 10
                   MAXVALUE 10000
              CYCLE--到10000后从头开始
              NOCACHE;


              影响Sequence的初始化参数:
              SEQUENCE_CACHE_ENTRIES=设置能同时被cache的sequence数目。

              可以很简单的Drop Sequence
              DRO SEQUENCE order_seq;

    -------------------------------------------------------------
    自增长及触发器:

         如何在Oracle中实现类似自动增加ID的功能?
              我们经常在设计数据库的时候用一个系统自动分配的ID来作为我们的主键,但是在ORACLE中没有这样的功能,我们可以通过采取以下的功能实现自动增加ID的功能
         1.首先创建sequence
              create sequence seq maxincrement by 1
         2.使用方法
              select seqmax.nextval ID from dual
         就得到了一个ID
         如果把这个语句放在触发器中,就可以实现和mssql的自动增加ID相同的功能!


    -------------------------------------------------------------------------
    Sql代码 复制代码 收藏代码
    1.      ###建表###   
    2.   
    3.      CREATE TABLE "SPORTS"."LINEUP"("ID" NUMBER NOT NULL,   
    4.           "TYPE" NUMBER(3) NOT NULL,   
    5.           "BODY" VARCHAR2(100) NOT NULL,   
    6.           "HITS" NUMBER(10) DEFAULT 0 NOT NULL,   
    7.           PRIMARYKEY("ID"))   
    8.      TABLESPACE "TS_SPORTS"  
    9.   
    10.      ###建序列###   
    11.   
    12.      CREATE SEQUENCE "SPORTS"."SPORTS_LINEUP_ID_SEQ" INCREMENT BY 1   
    13.      START WITH 1 MAXVALUE 1.0E28 MINVALUE 1 NOCYCLE   
    14.      CACHE 50 NOORDER   
    15.   
    16.      ###建自动更新的触发器###   
    17.   
    18.      CREATE OR REPLACE TRIGGER "SPORTS"."SPORTS_LINEUP_ID_TRIGGER"  
    19.      BEFORE INSERT ON "SPORTS"."LINEUP" FOR EACH ROW   
    20.      DECLARE  
    21.      next_id NUMBER;   
    22.      BEGIN  
    23.      --Get the next id number from the sequence   
    24.      SELECT sports_lineup_id_seq.NEXTVAL INTO next_id FROM dual;   
    25.   
    26.      --Use the sequence number as the primarykey   
    27.      --for there cord being inserted.   
    28.      :new.id:=next_id;   
    29.      END;   
    30.   
    31. ###建保护PRIMARYKEY的触发器###   
    32.   
    33.      CREATE OR REPLACE TRIGGER "SPORTS"."LINEUP_ID_UPDATE_TRIGGER"  
    34.           BEFORE UPDATE OF "ID" ON "SPORTS"."LINEUP" FOR EACHROW   
    35.      BEGIN  
    36.      RAISE_APPLICATION_ERROR(-20000,   
    37.      'sports_lineup_id_update_trigger:Update sof the ID field'  
    38.      ||'arenotallowed.');   
    39.      END;   
    40.   
    41. ###建删除的触发器###   
    42.      create   or replace trigger tr_bis_exc_req_del   
    43.      before delete  
    44.           on bis_exc_req   
    45.           referencing old as old new as new   
    46.      for each row   
    47.      begin  
    48.         if :old.check_status = '3' then  
    49.         raise_application_error (-20001,'*****!');   
    50.         return;   
    51.         end if;   
    52.      end;   
    53.      /   
    54.   
    55.   
    56. ###建更新的触发器###   
    57.      create   or replace trigger tr_bis_exc_req_upd   
    58.      before update  
    59.           on bis_exc_req   
    60.      referencing old as old new as new   
    61.      for each row   
    62.      begin  
    63.         if :old.check_status = '3' then  
    64.         raise_application_error (-20001,'*******!');   
    65.         return;   
    66.    end if;   
    67.   end;  
         ###建表###
    
         CREATE TABLE "SPORTS"."LINEUP"("ID" NUMBER NOT NULL,
              "TYPE" NUMBER(3) NOT NULL,
              "BODY" VARCHAR2(100) NOT NULL,
              "HITS" NUMBER(10) DEFAULT 0 NOT NULL,
              PRIMARYKEY("ID"))
         TABLESPACE "TS_SPORTS"
    
         ###建序列###
    
         CREATE SEQUENCE "SPORTS"."SPORTS_LINEUP_ID_SEQ" INCREMENT BY 1
         START WITH 1 MAXVALUE 1.0E28 MINVALUE 1 NOCYCLE
         CACHE 50 NOORDER
    
         ###建自动更新的触发器###
    
         CREATE OR REPLACE TRIGGER "SPORTS"."SPORTS_LINEUP_ID_TRIGGER"
         BEFORE INSERT ON "SPORTS"."LINEUP" FOR EACH ROW
         DECLARE
         next_id NUMBER;
         BEGIN
         --Get the next id number from the sequence
         SELECT sports_lineup_id_seq.NEXTVAL INTO next_id FROM dual;
    
         --Use the sequence number as the primarykey
         --for there cord being inserted.
         :new.id:=next_id;
         END;
    
    ###建保护PRIMARYKEY的触发器###
    
         CREATE OR REPLACE TRIGGER "SPORTS"."LINEUP_ID_UPDATE_TRIGGER"
              BEFORE UPDATE OF "ID" ON "SPORTS"."LINEUP" FOR EACHROW
         BEGIN
         RAISE_APPLICATION_ERROR(-20000,
         'sports_lineup_id_update_trigger:Update sof the ID field'
         ||'arenotallowed.');
         END;
    
    ###建删除的触发器###
         create   or replace trigger tr_bis_exc_req_del
         before delete
              on bis_exc_req
              referencing old as old new as new
         for each row
         begin
            if :old.check_status = '3' then
            raise_application_error (-20001,'*****!');
            return;
            end if;
         end;
         /
    
    
    ###建更新的触发器###
         create   or replace trigger tr_bis_exc_req_upd
         before update
              on bis_exc_req
         referencing old as old new as new
         for each row
         begin
            if :old.check_status = '3' then
            raise_application_error (-20001,'*******!');
            return;
       end if;
      end;
  • 相关阅读:
    jQuery 动画之 添加商品到购物车
    <% %> 、 <%= %> 、<%# %> 的区别
    WebFrom模拟MVC
    MVC 基础
    LinQ to SQL 存储过程
    Leetcode练习(Python):数组类:第26题:给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。
    Leetcode练习(Python):数组类:第18题:给定一个包含&#160;n 个整数的数组&#160;nums&#160;和一个目标值&#160;target,判断&#160;nums&#160;中是否存在四个元素 a,b,c&#160;和 d&#160;,
    Leetcode练习(Python):数组类:第16题:给定一个包括&#160;n 个整数的数组&#160;nums&#160;和 一个目标值&#160;target。找出&#160;nums&#160;中的三个整数,使得它们的和与&#160;target&#160;最接近。返回这三个数的和。假定每组输入只存在唯一答案。
    Leetcode练习(Python):数组类:第15题:给你一个包含 n 个整数的数组&#160;nums,判断&#160;nums&#160;中是否存在三个元素 a,b,c ,使得&#160;a + b + c = 0 ?请你找出所有满足条件且不重复的三元组。 注意:答案中不可以包含重复的三元组。
    Leetcode练习(Python):数组类:第11题:给你 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点&#160;(i,&#160;ai) 。在坐标内画 n 条垂直线,垂直线 i&#160;的两个端点分别为&#160;(i,&#160;ai) 和 (i, 0)。找出其中的两条线,使得它们与&#160;x&#160;轴共同构成的容器可以容纳最多的水。
  • 原文地址:https://www.cnblogs.com/wbzhao/p/2438947.html
Copyright © 2011-2022 走看看