身份种子在主键中达到现有值时会发生什么?

时间:2018-06-01 13:16:18

标签: sql sql-server sql-server-2017

我有一个标识列,它也是INT数据类型的主键。由于讨论的问题here(缓存丢失),身份有差距,我选择重新设置为先前的值。具体而言,我的情况如下:

表1

ID_PK    Field1
---------------
28       'd'
29       'e'
30       'h'
1029     'f'
1030     'g'

我环顾四周,无法找到一个明确的答案,当我进行插入时会发生什么,种子达到了会破坏约束的现有值。假设我要在表中的两个独立查询中插入值'x''y',我可以想到以下几种可能性:

  1. 在第一次插入之前,将重新标识身份,我将正确插入两个值。

  2. 第一次插入将失败,然后该列将重新播种,只有第二次插入才会成功。

  3. 两者都不起作用,我必须在表中插入值之前明确调用DBCC CHECKIDENT重新种植

  4. 那么,这是什么?或者以上都没有?如果我将多行结果查询插入Table1,这种行为会有所不同吗?提前致谢

3 个答案:

答案 0 :(得分:4)

无论如何,为了完整性,这里有一个可以用来测试的脚本:

USE Sandbox;
GO

CREATE TABLE test(ID int IDENTITY(1,1) PRIMARY KEY CLUSTERED, string char(1));
GO

INSERT INTO test (string)
VALUES ('a'),('b'),('c'),('d');
GO

SELECT *
FROM test;
GO

DELETE FROM test
WHERE string IN ('b','c');
GO

SELECT *
FROM test;
GO
DBCC CHECKIDENT ('dbo.test', RESEED, 1);
GO  
INSERT INTO test (string)
VALUES ('e'),('f');
GO

SELECT *
FROM test;
GO

INSERT INTO test (string)
VALUES ('g');
GO

SELECT *
FROM test;
GO
DROP TABLE test;

运行此脚本将为您提供所需的答案。如果您想知道为什么我使用1作为RESEED值,请在documentation中说明:

  

以下示例强制执行当前标识值   AddressType表中的AddressTypeID列的值为10。   因为表有现有行,所以插入的下一行将使用11   作为值,即为其定义的新当前增量值   列值加1。

在我的脚本中,这意味着要在RESEED之后插入的下一行的2值为IDENTITY,而不是1(作为行)已存在于表格中(ID为14))。

正如有些人在评论中所说,实际上没有必要在RESEED列上使用IDENTITY。如果您需要维护序列,您应该(不出所料)使用SEQUENCECREATE SEQUENCE (Transact-SQL)

答案 1 :(得分:2)

取决于:

场景1

您在IDENTITY列中获得重复项,因为没有唯一索引或PK约束。

create table I (
    id int identity(1,1) not null,
    i int null
)

场景2

由于插入的值与主键约束冲突,您会收到以下错误:

  

Msg 2627,Level 14,State 1,Line 1违反PRIMARY KEY   约束' PK__I__3213E83FE0B0E009'。无法插入重复键   对象' dbo.I'。重复键值为(11)。声明有   已被终止。

create table I (
    id int identity(1,1) not null primary key,
    i int null
)

这证明IDENTITY上的UNIQUE CONSTRAINT不保证唯一性,只有<?php /* Theme Test Data */ class theme_test_data extends WP_Customize_Section { public $type = "theme_test_data"; public $test_url = ""; public $test_text = ""; public $test_link_text = ""; public function json() { $json = parent::json(); $json['test_text'] = $this->test_text; $json['test_link_text'] = $this->test_link_text; $json['test_url'] = esc_url( $this->test_url ); return $json; } public function render_template() {?> <li id="accordion-section-{{ data.id }}" class="accordion-section control-section control-section-{{ data.type }}"> <form method="POST" action="{{data.test_url}}"> <input type="hidden" name="testdatainstall" value="1"/> <?php wp_nonce_field('theme.initialize');?> <h3 class="accordion-section-title"> <span>{{data.test_text}}</span> <button type="submit" class="theme_customizer_doc_button btn">{{data.test_link_text}}</button> </h3> </form> </li> <?php } } //Theme registration $wp_customize->register_section_type( 'theme_test_data' ); //Add section $wp_customize->add_section(new theme_test_data($wp_customize, 'theme_test_data', array( 'title' => __('Section Title', 'theme_language'), 'test_url' => admin_url('edit.php'), 'test_text' => __('Install our test data', 'theme_language'), 'test_link_text' => __('Install', 'theme_language'), 'priority' => 1000 ))); 才能保证唯一性。

答案 2 :(得分:0)

要关闭,结果是(2)。

首次插入失败,重新设置自动到最高值,只有下一次插入才会成功。如果任何值会破坏主键约束,则多值插入的行为相同。