温馨提示:本文翻译自stackoverflow.com,查看原文请点击:php - Autoincrement value is changing when database error occured in sql server 2014
codeigniter php sql sql-server

php - 当SQL Server 2014中发生数据库错误时,自动增量值将更改

发布于 2020-03-27 12:06:07

在此处输入图片说明 Contract_id是主键及其自动增量值

我在将数据添加到数据库时使用sql server 2014和codeigniter,在将数据插入数据库时​​遇到错误。问题是日期格式问题。我已解决此问题并再次成功插入数据库。

但是问题是Autoincrement(主键)值正在跳过并且序列的Next值也正在更改。当前端出现数据库错误时如何停止跳过autoincrement值?

public function save_contract() { 

        date_default_timezone_set('Asia/Dubai');
        //$created_Dt        = '2019-07-03';
        $created_Dt        = date('Y-m-d H:i:s');
        $this->db->select('NEXT VALUE FOR contacts_seq as contractid');
        $query = $this->db->get();

        foreach ($query->result_array() as $row)
        {
           $contract_number = $row['contractid'];
           //echo $contract_number;
        }



    $data = array(
           'Contract_no' => $this->input->post('getcontract_no'). $contract_number,
            'status' => "active",
            'created_Dt' => $created_Dt
        );

 $insert_id = 0;
     if($this->db->insert("contract", $data)){
        $insert_id = $this->db->insert_id();
        }
       return $contract_number;

    }

创建的序列

CREATE SEQUENCE  contacts_seq AS INT
 START WITH 1
 INCREMENT BY 1

查看更多

查看更多

提问者
duo
被浏览
159
Larnu 2019-07-03 23:51

IDENTITY属性不会重用值。IDENTITY(Transact-SQ)-备注(我加强调):

列上的identity属性不能保证满足以下条件:

  • 值的唯一性-必须通过使用PRIMARY KEY或UNIQUE约束或UNIQUE索引来强制执行唯一性。

  • 事务内的连续值-不能保证插入多行的事务获取行的连续值,因为表上可能会发生其他并发插入。如果值必须是连续的,则事务应在表上使用排他锁或使用SERIALIZABLE隔离级别。

  • 服务器重新启动或其他故障后的连续值-由于性能原因,SQL Server可能会缓存标识值,并且在数据库故障或服务器重新启动期间某些分配的值可能会丢失。这可能导致插入时身份值出现空白。如果差距不可接受,则应用程序应使用自己的机制来生成键值。将序列生成器与NOCACHE选项一起使用可以将间隔限制为从未提交的事务。

  • 值的重用-对于具有特定种子/增量的给定身份属性,引擎不会重用身份值。如果特定的插入语句失败或插入语句回滚,则消耗的标识值将丢失并且将不会再次生成。当生成后续标识值时,这可能会导致出现间隙。

这些限制是设计的一部分,目的是提高性能,并且因为它们在许多常见情况下都是可以接受的。如果由于这些限制而无法使用标识值,请创建一个包含当前值的单独表,并管理对表的访问以及应用程序的编号分配。

这意味着,如果您INSERT由于行原因而回滚了事务,则无论出于何种原因,该种子都将不会被重用。如果删除行,也是如此。现有的行将不会重新播种,然后使用“新”的下一个值;您的人数会有差距。

的值IDENTITY纯粹是从关系的角度使用的,而不是在要维护的表中创建连续的值。如果要在运行时使用连续值,则应使用ROW_NUMBER如果要存储它们,最好查看SEQUENCE