如何自动增加非主键? - SQL 服务器

Posted

技术标签:

【中文标题】如何自动增加非主键? - SQL 服务器【英文标题】:How to Auto-Increment Non-Primary Key? - SQL Server 【发布时间】:2011-02-05 18:27:11 【问题描述】:
CREATE TABLE SupplierQuote
(
supplierQuoteID int identity (3504,2) CONSTRAINT supquoteid_pk PRIMARY KEY,
PONumber int identity (9553,20) NOT NULL
.
.
.
CONSTRAINT ponumber_uq UNIQUE(PONumber)
);

上面的ddl产生错误:

消息 2744,第 16 级,状态 2,第 1 行 指定了多个标识列 对于表“供应商报价”。只有一个 允许每个表的标识列。

我该如何解决?我希望 PONumber 自动递增。

【问题讨论】:

【参考方案1】:

您无法解决您的问题 - 每个表只能有一个 IDENTITY 列。没办法,抱歉。

唯一的“hackish”解决方案是拥有一个单独的表,只需要一个 INT IDENTITY 字段,并在插入时从该帮助表中获取最新值到您的实体中(例如,使用触发器)。不是很漂亮,但它可能适合你。

【讨论】:

【参考方案2】:

每个表不能有多个标识列。我认为您最好的选择是将 PO 数据提取到单独的表中,然后将两者与 FK 列相关联。

SupplierQuote
-------------
supplierQuoteID (PK/identity)
purchaseOrderID (FK to PurchaseOrder.purchaseOrderID)
otherColumn1

PurchaseOrder
-------------
purchaseOrderID (PK/identity)
otherColumn1

【讨论】:

问题是当supplierQuoteID记录被删除时,父表中的purchaseOrder就没有用了。因此,我将不得不编写一个触发器来擦除父 purchaseOrder 记录。我决定使用随机生成器从前端手动插入 PONumber。 如果您想确保 PONumber 是唯一的,我不会使用随机数生成器。我会使用 Guid.NewGuid()。保证数据库唯一性的两种最简单的方法是使用标识或 GUID。 您也可以级联删除 - 当您删除供应商报价时,您将删除设置为级联到关联的 PurchaseOrder 记录,只要它不与任何其他供应商报价相关联。 从随机数生成器插入 po 号码是一个非常冒险的举动。实际上不要这样做。【参考方案3】:

如果在插入行时生成了 SupplierQuoteId 和 PONumber,则两个“身份”列将被同步分配(3504 与 9553 一起,3506 与 9573 一起,3508 与 9593 一起,等等)。如果这个假设成立,那么您大概可以将 PONumber 设为计算列,如下所示:

CREATE TABLE SupplierQuote 
( 
supplierQuoteID int NOT NULL identity (3504,2) CONSTRAINT supquoteid_pk PRIMARY KEY, 
PONumber AS (10 * supplierQuoteID - 25487)
. 
. 
. 
); 

我将supplierQuoteId 设为NOT NULL,这样可以确保PONumber 也不会为NULL。同样,您不再需要 PONumber 上的唯一约束,因为它始终是唯一的。 (如果您需要索引以提高性能,则可以在计算列上构建索引。)

【讨论】:

【参考方案4】:

我想我会使用触发器来填充“第二个身份”。

【讨论】:

【参考方案5】:

如果每个供应商报价只有一个 PO id,那么为什么不简单地使用供应商报价 ID 作为 PO id?

如果可以有多个,则必须有一个带有外键约束的单独表。您当然可以使用级联删除从该表中删除,但如果您删除太多记录(导致锁定),或者我个人不想删除供应商报价,如果已创建采购订单编号,这意味着引用的项目实际上是购买的。您永远不想破坏实际购买的东西的记录。由于每个报价您可能会有多个 POS(我得到了六件商品的报价,首先购买了其中三件,然后在下周购买了另外两件),并且由于您可能想要存储有关采购订单的特定信息,所以我推荐一个单独的表。从长远来看,做任何其他事情都会给你带来麻烦。

【讨论】:

【参考方案6】:

绕过非标识列中的自动增量。(MS SQL)虽然我认为这不是最佳实践!只是一个快速修复解决方案。

    INSERT INTO [dbo].[Employee]
           ([EmpID]
           ,[Name]
           ,[Salary]
           ,[Address]
           ,[datecoded])
     VALUES
           ( (select top 1 EmpID from dbo.Employee order by EmpID desc) + 1
           , 'name_value'
           , 123456
           ,'address_value'
           , GETDATE())

【讨论】:

以上是关于如何自动增加非主键? - SQL 服务器的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 4:如何使用迁移创建非主自动递增列?

在 SQL Server 中的非主键上添加 @ManyToOne 映射时出现问题

如何将自动增量设置为非主键?

MySQL主键索引非主键索引以及SQL语句中如何利用索引的

MySQL主键索引非主键索引以及SQL语句中如何利用索引的

SQL如何实现主键数字自动增加?(SQLSERVER)