zoukankan      html  css  js  c++  java
  • 三、MySQL 替代 Oracle 序列以及自增长处理

    一、MySQL 替代 Oracle 序列以及自增长处理

    什么是自增长?

    • 自增长只能用于表中的其中一个字段。
    • 自增长只能被分配给固定表的固定的某一字段,不能被多个表共用。
    • 自增长会把一个未指定或NULL值的字段自动填上。
    一、在 Oracle 中如何实现 MySQL 的自增长?

    请看下面的实例:

    • 1-1、在 MYSQL 里有这样一张表:
    CREATE TABLE Movie(  
      id           INT NOT NULL AUTO_INCREMENT,  
      name     VARCHAR(60) NOT NULL,  
      released YEAR NOT NULL,  
      PRIMARY KEY (id)  
    ) ENGINE=InnoDB;  
    
    INSERT INTO Movie (name,released) VALUES ('Gladiator',2000);  
    INSERT INTO Movie (id,name,released) VALUES (NULL,'The Bourne Identity',1998);  
    • 1-2、在 ORACLE 是这样的使用序列对象+触发器来完成 MySQL 的自增长功能
    CREATE TABLE Movie(  
     id          INT NOT NULL,  
     name     VARCHAR2(60) NOT NULL,  
     released INT NOT NULL,  
     PRIMARY KEY (id)  
    );  
    CREATE SEQUENCE MovieSeq;  
    INSERT INTO Movie (id,name,released) VALUES (MovieSeq.NEXTVAL,'Gladiator',2000);  

    在 Oracle 下为表添加一个触发器,就可以实现 MySQL 自增长功能:

    1.  CREATE OR REPLACE TRIGGER BRI_MOVIE_TRG  
    2.  BEFORE INSERT ON Movie  
    3.  FOR EACH ROW  
    4.  BEGIN  
    5.  SELECT MovieSeq.NEXTVAL INTO :new.id FROM DUAL;  
    6.  END BRI_MOVIE_TRG;  
    7.  .  
    8.  RUN;  

    这样,插入记录就可以成为 MYSQL 风格:

    INSERT INTO Movie (name,released) VALUES ('The Lion King',1994);  

    下面我们来看看如何在 mysql 数据里使用 Oracle 序列语法 .NEXTVAL 和 .CURVAL。

    二、MySQL 如何实现 Oracle 序列?

    一般使用序列 (Sequence) 来处理主键字段,在 MySQL中 是没有序列的,但是 MySQL有提供了自增长 (increment) 来实现类似的目的,但也只是自增,而不能设置步长、开始索引、是否循环等,最重要的是一张表只能由一个字段使用自增,但有的时候我们需要两个或两个以上的字段实现自增(单表多字段自增),MySQL本身是实现不了的,但我们可以用创建一个序列表,使用函数来获取序列的值。

    我们假设在 MySQL 中序列的语法是:

    NEXTVAL(’sequence’);
    CURRVAL(’sequence’);
    SETVAL(’sequence’,value);
    DROP TABLE IF EXISTS sequence;  
    CREATE TABLE sequence (  
    name              VARCHAR(50) NOT NULL,  
    current_value INT NOT NULL,  
    increment       INT NOT NULL DEFAULT 1,  
    PRIMARY KEY (name)  
    ) ENGINE=InnoDB;  
    
     INSERT INTO sequence VALUES ('MovieSeq',3,5); 
    
    测试一下结果:

    测试 currval 函数使用

    /* currval 函数的实现 */
     DROP FUNCTION IF EXISTS currval;  
     DELIMITER $  
     CREATE FUNCTION currval (seq_name VARCHAR(50))  
     RETURNS INTEGER  
     CONTAINS SQL  
     BEGIN  
     DECLARE value INTEGER;  
     SET value = 0;  
     SELECT current_value INTO value  
     FROM sequence  
     WHERE name = seq_name;  
     RETURN value;  
     END$  
     DELIMITER ;
    1.  mysql> SELECT currval('MovieSeq');  
    2.  +---------------------+  
    3.  | currval('MovieSeq') |  
    4.  +---------------------+  
    5.  |                   3 |  
    6.  +---------------------+  
    7.  1 row in set (0.00 sec)  
    8.  mysql> SELECT currval('x');  
    9.  +--------------+  
    10.  | currval('x') |  
    11.  +--------------+  
    12.  |            0 |  
    13.  +--------------+  
    14.  1 row in set, 1 warning (0.00 sec)  
    15.  mysql> show warnings;  
    16.  +---------+------+------------------+  
    17.  | Level   | Code | Message          |  
    18.  +---------+------+------------------+  
    19.  | Warning | 1329 | No data to FETCH |  
    20.  +---------+------+------------------+  
    21.  1 row in set (0.00 sec)  

    测试 nextval 函数使用

    /* nextval 函数的实现 */
    DROP FUNCTION IF EXISTS nextval;  
    DELIMITER $  
    CREATE FUNCTION nextval (seq_name VARCHAR(50))  
    RETURNS INTEGER  
    CONTAINS SQL  
    BEGIN  
    UPDATE sequence  
    SET          current_value = current_value + increment  
    WHERE name = seq_name;  
    RETURN currval(seq_name);  
    END$  
    DELIMITER ;  
    1.  mysql> select nextval('MovieSeq');  
    2.  +---------------------+  
    3.  | nextval('MovieSeq') |  
    4.  +---------------------+  
    5.  |                  15 |  
    6.  +---------------------+  
    7.  1 row in set (0.09 sec)  
    
    9.  mysql> select nextval('MovieSeq');  
    10.  +---------------------+  
    11.  | nextval('MovieSeq') |  
    12.  +---------------------+  
    13.  |                  20 |  
    14.  +---------------------+  
    15.  1 row in set (0.01 sec)  
    
    17.  mysql> select nextval('MovieSeq');  
    18.  +---------------------+  
    19.  | nextval('MovieSeq') |  
    20.  +---------------------+  
    21.  |                  25 |  
    22.  +---------------------+  
    23.  1 row in set (0.00 sec)  

    测试 setval 函数的使用

    /* setval 函数的实现 */
    DROP FUNCTION IF EXISTS setval;  
    DELIMITER $  
    CREATE FUNCTION setval (seq_name VARCHAR(50), value INTEGER)  
    RETURNS INTEGER  
    CONTAINS SQL  
    BEGIN  
    UPDATE sequence  
    SET          current_value = value  
    WHERE name = seq_name;  
    RETURN currval(seq_name);  
    END$  
    DELIMITER ;  
    1.  mysql> select setval('MovieSeq',150);  
    2.  +------------------------+  
    3.  | setval('MovieSeq',150) |  
    4.  +------------------------+  
    5.  |                    150 |  
    6.  +------------------------+  
    7.  1 row in set (0.06 sec)  
    
    9.  mysql> select curval('MovieSeq');  
    10.  +---------------------+  
    11.  | currval('MovieSeq') |  
    12.  +---------------------+  
    13.  |                 150 |  
    14.  +---------------------+  
    15.  1 row in set (0.00 sec)  
    
    17.  mysql> select nextval('MovieSeq');  
    18.  +---------------------+  
    19.  | nextval('MovieSeq') |  
    20.  +---------------------+  
    21.  |                 155 |  
    22.  +---------------------+  
    23.  1 row in set (0.00 sec)
    三、MySQL 替代 Oracle 序列实例:
    • 1、问题场景:
      一般使用序列 (Sequence) 来处理主键字段,在 MySQL中 是没有序列的,但是 MySQL有提供了自增长 (increment) 来实现类似的目的,但也只是自增,而不能设置步长、开始索引、是否循环等,最重要的是一张表只能由一个字段使用自增,但有的时候我们需要两个或两个以上的字段实现自增(单表多字段自增),MySQL本身是实现不了的,但我们可以用创建一个序列表,使用函数来获取序列的值。

    -- MySQL 给数据表某个字段创建序列。
    -- 序列:自增(步长、开始索引、是否循环),暂不考虑是否循环自增(触发器可实现?)
    select * from PAN_WF_HISTORYNODE;-- ORDER_NUMBER 字段创建序列

    -- 创建代替序列的数据表

    DROP TABLE IF EXISTS sequence;  
    CREATE TABLE sequence (  
    name              VARCHAR(50) NOT NULL, -- 序列 名称 50个字符最大值问题已够用,暂不考虑是否循环。
    current_value INT NOT NULL,  -- 当前值
    increment       INT NOT NULL DEFAULT 1,  -- 步长
    PRIMARY KEY (name)  
    ) ENGINE=InnoDB;  
    INSERT INTO sequence VALUES ('seq_hisnode',0,1);

    -- 处理 序列的 currval 函数

    Set global log_bin_trust_function_creators=1;-- 解决自定义函数报错:ERROR 1418-This function has none of DETERMINISTIC
    
    DROP FUNCTION IF EXISTS currval;  
    DELIMITER $  
    CREATE FUNCTION currval (seq_name VARCHAR(50))  
    RETURNS INTEGER  
    CONTAINS SQL  
    BEGIN  
      DECLARE value INTEGER;  
      SET value = 0;  
      SELECT current_value INTO value  
      FROM sequence  
      WHERE name = seq_name;  
      RETURN value;  
    END$  
    DELIMITER ;  
    
    SELECT currval('seq_hisnode');-- 测试 该函数的使用。

    -- 处理序列的 nextval 函数

    DROP FUNCTION IF EXISTS nextval;  
    DELIMITER $  
    CREATE FUNCTION nextval (seq_name VARCHAR(50))  
    RETURNS INTEGER  
    CONTAINS SQL  
    BEGIN  
       UPDATE sequence  
       SET          current_value = current_value + increment  
       WHERE name = seq_name;  
       RETURN currval(seq_name);  
    END$  
    DELIMITER ;
    
    select nextval('seq_hisnode');
    INSERT into PAN_WF_HISTORYNODE values()
  • 相关阅读:
    Servlet获取URL地址
    js实现浏览器通知功能
    利用Hibernate监听器实现用户操作日志
    XMLHttpRequest上传文件实现进度条
    事务配置中的一些要点
    Spring事务配置的五种方式
    基于注解的Spring AOP的配置和使用
    @ResponseBody注解与JSON
    springMVC获取request和response
    Highcharts属性介绍
  • 原文地址:https://www.cnblogs.com/pengguozhen/p/15170686.html
Copyright © 2011-2022 走看看