8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

如何在 MySQL 中创建序列?

MikeBeaton 2月前

91 0

我正在尝试在 MySQL 中创建一个序列(我对 SQL 整体上非常陌生)。我正在使用以下代码,但它导致错误:CREATE SEQUENCE ORDID INCREMENT BY 1 START WITH 622;ORDID 指的是...

我正在尝试在 MySQL 中创建一个序列(我对 SQL 整体来说非常陌生)。我正在使用以下代码,但它会导致错误:

CREATE SEQUENCE ORDID INCREMENT BY 1 START WITH 622;

ORDID 指的是我正在使用的表中的一个字段。如何正确创建序列?

编辑:

据称,MySQL 不使用序列。我现在正在使用以下代码,但这也会导致错误。我该如何修复它们?

CREATE TABLE ORD (
ORDID NUMERIC(4) NOT NULL AUTO_INCREMENT START WITH 622,
//Rest of table code

编辑:

我想我找到了解决办法。对于 phpMyAdmin(我正在使用),您可以使用以下代码。

ALTER TABLE ORD AUTO_INCREMENT = 622;

我不知道它为什么喜欢这样,但如果其他人需要帮助,那么你可以去这里。:)

帖子版权声明 1、本帖标题:如何在 MySQL 中创建序列?
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由MikeBeaton在本站《ubuntu》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 将“AUTO_INCREMENT”添加到 ORDID 字段只会导致另一个错误。不过,有一个“INCREMENT”函数。这能行吗?

  • 看看 这篇文章 。我相信它应该能帮助你得到你想要的东西。如果你的表已经存在,并且其中已经有数据,那么你得到的错误可能是由于 auto_increment 试图为其他记录分配一个已经存在的值。

    简而言之,正如其他人在评论中提到的那样,在 Oracle 中考虑和处理的序列在 MySQL 中并不存在。但是,您可能可以使用 auto_increment 来实现您想要的功能。

    如果没有有关特定错误的更多详细信息,则很难提供更具体的帮助。

    更新

    CREATE TABLE ORD (
      ORDID INT NOT NULL AUTO_INCREMENT,
      //Rest of table code
      PRIMARY KEY (ordid)
    )
    AUTO_INCREMENT = 622;
    

    此链接 对于描述 auto_increment 的用法也很有用。设置 AUTO_INCREMENT 值似乎是一个 表选项 ,而不是专门指定为列属性的东西。

    此外,按照上面的一个链接,您也可以通过更改表来设置自动增量的起始值。

    ALTER TABLE ORD AUTO_INCREMENT = 622;
    

    更新 2 使用自动增量的 有效 SQLFiddle 示例 的链接
    我希望这些信息能有所帮助。

  • H.C. 2月前 0 只看Ta
    引用 4

    我每次都使用大量代码从头开始创建表(如果出现问题,我会删除表并重新开始)。MySQL 以前从未遇到过 \'numeric(4)\' 问题。

  • 额外的信息:我在 \'phpMyAdmin\' 上使用 MySQL 服务器。不确定这是否有帮助,但我觉得它在 AUTO_INCREMENT 命令上存在问题。

  • Stack Overflow 上还有另一个链接,讨论了 phpMyAdmin 中 AUTO_INCREMENT 的使用:.com/questions/5665571/…

  • MySQl 手册建议的 解决方案 :

    如果 expr 作为 LAST_INSERT_ID() 的参数给出,则该函数将返回该参数的值,并将其记住为 LAST_INSERT_ID() 要返回的下一个值。这可用于模拟序列:

    创建一个表来保存序列计数器并初始化它:

        mysql> CREATE TABLE sequence (id INT NOT NULL);
        mysql> INSERT INTO sequence VALUES (0);
    

    使用该表生成如下序列号:

        mysql> UPDATE sequence SET id=LAST_INSERT_ID(id+1);
        mysql> SELECT LAST_INSERT_ID();
    

    UPDATE 语句增加序列计数器并导致下次调用 LAST_INSERT_ID() 返回更新的值。SELECT 语句检索该值。mysql_insert_id() C API 函数也可用于获取该值。请参见第 23.8.7.37 节“mysql_insert_id()”。

    无需调用 LAST_INSERT_ID() 即可生成序列,但这样使用该函数的好处是,ID 值在服务器中作为最后自动生成的值保留。它对多用户安全,因为多个客户端可以发出 UPDATE 语句并使用 SELECT 语句(或 mysql_insert_id())获取自己的序列值,而不会影响或受生成自己序列值的其他客户端的影响。

  • 这是迄今为止最好的“序列”解决方案,包装到存储过程中:DELIMITER $$ CREATE PROCEDURE seq_next_id() BEGIN START TRANSACTION; UPDATE serial SET id=LAST_INSERT_ID(id + 1); SELECT LAST_INSERT_ID() AS number; COMMIT; END $$ DELIMITER ;

  • 关于这个十年前的答案,我认为它已从 mysql 手册中删除。这是一个非常粗制滥造的想法,很惊讶他们提出了这个建议。也许我错了,它被移动了还是怎么了?

  • SEQUENCES like it works on firebird:

    -- ================================================== =======

    CREATE TABLE SEQUENCES  
    (  
      NM_SEQUENCE VARCHAR(32) NOT NULL UNIQUE,  
      VR_SEQUENCE BIGINT      NOT NULL  
    );  
    

    -- ================================================== =======
    -- 创建一个序列 sSeqName 并设置其初始值。
    -- ================================================== =======

    DROP PROCEDURE IF EXISTS CreateSequence;  
    
    DELIMITER :)  
    CREATE PROCEDURE CreateSequence( sSeqName VARCHAR(32), iSeqValue BIGINT )  
    BEGIN  
      IF NOT EXISTS ( SELECT * FROM SEQUENCES WHERE (NM_SEQUENCE = sSeqName) ) THEN  
        INSERT INTO SEQUENCES (NM_SEQUENCE, VR_SEQUENCE)  
        VALUES (sSeqName   , iSeqValue  );  
      END IF;  
    END :)  
    DELIMITER ;  
    
    -- CALL CreateSequence( 'MySequence', 0 );  
    

    -- ================================================== =======================
    -- 将 sSeqName 的序列值增加 iIncrement 并返回。
    -- 如果 iIncrement 为零,则返回 sSeqName 的当前值。
    -- ================================================== =======================

    DROP FUNCTION IF EXISTS GetSequenceVal;  
    
    DELIMITER :)  
    CREATE FUNCTION GetSequenceVal( sSeqName VARCHAR(32), iIncrement INTEGER )  
    RETURNS BIGINT  -- iIncrement can be negative  
    BEGIN  
      DECLARE iSeqValue BIGINT;  
    
      SELECT VR_SEQUENCE FROM SEQUENCES  
      WHERE  ( NM_SEQUENCE = sSeqName )  
      INTO   @iSeqValue;  
    
      IF ( iIncrement <> 0 ) THEN  
        SET @iSeqValue = @iSeqValue + iIncrement;  
    
        UPDATE SEQUENCES SET VR_SEQUENCE = @iSeqValue  
        WHERE  ( NM_SEQUENCE = sSeqName );  
      END IF;
    
      RETURN @iSeqValue;
    END :)  
    DELIMITER ;  
    
    -- SELECT GetSequenceVal('MySequence', 1);  -- Adds 1 to MySequence value and returns it.
    

    -- ================================================== ===================

  • 你好,Antonov,在像 Firebird 这样的并发 GetSequenceVal 调用中,序列值是否唯一?

  • 通过创建增量表,您应该注意不要删除插入的行。这样做的原因是为了避免在数据库中存储带有 ID 的大量哑数据。否则,如果 mysql 重新启动,它将获取最大现有行并从该点继续增量,如文档 http://dev.mysql.com/doc/refman/5.0/en/innodb-auto-increment-handling.html

  • 如果您需要与 AUTO_INCREMENT 不同的东西,您仍然可以使用触发器。

  • 我的意思是您可以将触发器用于“任何事情”,它们是一种图灵机,是的,在某些特定用例中它可能是相关的。

  • 引用 15

    纯粹为了记录这个奇怪的老问题,这里概述了在没有可用序列时模拟序列的标准方法。看来 MySql 没有它们,所以在这里。

    首先,确切的说……

    mysql>  CREATE TABLE `ubersequence` (
        ->  `id` int NOT NULL AUTO_INCREMENT,
        ->  `unused` varchar(32) not null unique,
        ->  PRIMARY KEY (`id`) );
    Query OK, 0 rows affected (0.05 sec)
    
    mysql> insert into ubersequence (unused) values ('snap');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from ubersequence ;
    +----+--------+
    | id | unused |
    +----+--------+
    |  1 | snap   |
    +----+--------+
    1 row in set (0.00 sec)
    

    每次需要下一个值时, just replace in to it ,然后读取新的 ID。

    mysql> replace into ubersequence (unused) values ('snap') ;
    Query OK, 2 rows affected (0.01 sec)
    
    mysql> select * from ubersequence ;
    +----+--------+
    | id | unused |
    +----+--------+
    |  2 | snap   |
    +----+--------+
    1 row in set (0.00 sec)
    
    mysql> replace into ubersequence (unused) values ('snap') ;
    Query OK, 2 rows affected (0.01 sec)
    
    mysql> select * from ubersequence ;
    +----+--------+
    | id | unused |
    +----+--------+
    |  3 | snap   |
    +----+--------+
    1 row in set (0.00 sec)
    

    不要重复超过二十亿次!

    请注意,当然 这两个步骤以及可能更多的步骤必须是代码中的原子事务 .

    感谢@Barmar 明确指出 MySql 没有全局序列。

  • 我发现这对我来说很有效。告诉 MYSQL 您正在更改列,但保留相同的名称:

    改变表 ORD 更改 ORDID ORDID int(10) 无符号自动增量;

    这告诉 ORD 表中的 ORDID 列开始自动递增。然后发出以下命令:

    更改表 ORD AUTO_INCREMENT = 85;

    例如,从 85 开始下一行。

返回
作者最近主题: