如何自动递增非主键? - SQL Server

18
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产生了一个错误:

Msg 2744,级别16,状态2,第1行 指定了多个标识列,表'SupplierQuote'。每个表只允许一个标识列。

我该怎么解决?我希望PONumber自动递增。

6个回答

9

如果在插入行时生成了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也是NOT NULL。同样地,您不再需要在PONumber上设置唯一约束,因为它将始终是唯一的。(如果需要性能方面的索引,可以在计算列上建立索引。)


7

每个表只能有一个标识列。我认为你最好的选择是将PO数据拉到一个单独的表中,然后使用FK列将两个表关联起来。

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

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

问题在于当supplierQuoteID记录被删除时,父表中的purchaseOrder将变得无用。因此,我必须编写触发器或其他方式来清除父级purchaseOrder记录。我决定通过使用随机生成器之类的前端手动插入PONumber。 - user311509
如果您想确保PONumbers唯一,我不建议使用随机数生成器,而是应该使用Guid.NewGuid()。在数据库中保证唯一性的两种最简单的方法是使用Identity或GUID。 - Andy White
您还可以级联删除 - 当您删除供应商报价时,您可以设置删除操作级联到相关的采购订单记录,只要该采购订单未与任何其他供应商报价关联。 - Andy White
从随机数生成器中插入PO号是非常冒险的行为,请不要这样做。 - HLGEM

2

您无法解决这个问题 - 每个表只能有一个IDENTITY列。很抱歉,没有绕过这个限制的方法。

唯一“hackish”的解决方案是为此单独创建一个表,仅具有INT IDENTITY字段,并在插入时从该辅助表中获取最新值到您的实体中(例如使用触发器)。这并不美观,但可能对您有用。


1
如果每个供应商报价只有一个PO id,那么为什么不直接使用供应商报价id作为PO id呢?
如果可能存在多个PO id,您必须使用一个带有外键约束的单独表。当然,您可以使用级联删除来从此表中删除数据,但是如果删除太多记录(导致锁定),或者个人觉得如果已经创建了PO号码,就不想删除供应商报价,因为这意味着实际上购买了所报价的物品。您不希望永远销毁实际购买的记录。由于您可能会对每个报价有多个POS(我有六样东西报价,并且第一周买了其中三样,然后下周再买了另外两样),并且由于您可能希望存储有关采购订单的特定信息,我建议使用一个单独的表。做其他任何事情都将在长期运行中给您带来问题。

0

绕过非自增列的自动递增。(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())

0

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接