【问题标题】:SQL Server 2008 R2 : after manual record insert into column with unique key index constraintSQL Server 2008 R2:手动记录插入具有唯一键索引约束的列后
【发布时间】:2017-03-22 17:20:13
【问题描述】:

我有一个应用程序,允许用户将记录插入到表中,该表的列具有定义为的唯一键索引约束

CREATE UNIQUE NONCLUSTERED INDEX [my_IDX2] 
    ON [dbo].[myTable] ([seq_no] ASC)

完美运行,但是在使用SSMS将不相关且成功的手动记录数据库插入同一张表后,无法通过应用添加后续记录,这是错误消息:

数据库错误代码:2601

数据库错误信息:
SQLSTATE = 23000
适用于 SQL Server 的 Microsoft OLE DB 提供程序
无法在具有唯一索引“my_IDX2”的对象“dbo.myTable”中插入重复的键行。

在我看来,解决方法是将my_IDX2 索引增加到我在手动插入期间使用的最后一个值(+1),但这可能吗?怎么样?

【问题讨论】:

  • 您是否使用sequence 而不是identity
  • 两者都不是。 [seq_no] 是列的名称,其中的值似乎增加了 1。当通过应用程序添加记录时,它显然会获得下一个增量。当我直接插入一条记录时,我可能会错过对索引的调用以给我下一个值。我需要以某种方式重新定义 my_IDX2 索引的下一个值,但我不知道该怎么做
  • 索引不提供值。我想你一定是在谈论一个序列。
  • 也许吧。是否可以调整序列以使用某个值?我的问题不在于它是身份还是序列。真正的问题是如何增加、调整、重置为不同的值或重新建立新的下一个值。

标签: sql-server indexing key constraints unique


【解决方案1】:

如果您使用sequence,然后手动插入顺序值,sequence 对象不知道这一点。它只跟踪它生成的数字。当您希望将唯一编号的单一来源用于多个表格时,这非常有用。

另一方面,identity 会跟踪它生成的值,但也会考虑手动插入表中的其他值。

下面是sequenceidentity 对它们未生成的插入值的反应的快速比较。

测试设置:http://rextester.com/VDDF36095

/* ------------- using sequence ----------- */
create sequence organisation_seq as bigint 
  start with 1 increment by 1;
create table organisation
(
  id bigint not null default next value for organisation_seq,
  customer_number varchar(50) unique
);

insert into organisation values
 (next value for organisation_seq, 'a')
,(200, 'b')
,(next value for organisation_seq, 'c');

select * from organisation;

返回:

+-----+-----------------+
| id  | customer_number |
+-----+-----------------+
|   1 | a               |
| 200 | b               |
|   2 | c               |
+-----+-----------------+

如果您改用identity

/* ------------- using identity ----------- */
create table organisation_identity
(
  id bigint not null identity (1,1),
  customer_number varchar(50) unique
);

insert into organisation_identity values
('a');

/* ------------- identity_insert on ----------- */
set identity_insert organisation_identity on;
insert into organisation_identity (id, customer_number) values
(200, 'b');
set identity_insert organisation_identity off;
/* ------------- identity_insert off ----------- */

insert into organisation_identity values
('c');

select * from organisation_identity;

返回:

+-----+-----------------+
| id  | customer_number |
+-----+-----------------+
|   1 | a               |
| 200 | b               |
| 201 | c               |
+-----+-----------------+

对于任何一种情况,一个肮脏的解决方法是只为您的sequenceidentity 使用正整数,并为手动插入的值获取min(id)-1

序列参考:

身份参考:

【讨论】:

    【解决方案2】:

    谜团解开了!我在应用程序的数据库中找到了一个单独的表,用于管理所有序列,虽然设计很奇怪,但还可以。一旦我找到具体记录并调整下一个值,问题就消失了。感谢大家的回复。

    【讨论】:

      猜你喜欢
      • 2013-01-01
      • 1970-01-01
      • 2011-07-08
      • 2014-11-28
      • 2012-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多