如何自动增加非主键? - 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 服务器的主要内容,如果未能解决你的问题,请参考以下文章