2010-04-08 112 views
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產生一個錯誤:如何自動遞增非主鍵? - SQL服務器

Msg 2744, Level 16, State 2, Line 1 Multiple identity columns specified for table 'SupplierQuote'. Only one identity column per table is allowed.

我該如何解決呢?我想讓PONumber自動遞增。

回答

7

每個表不能有多個標識列。我認爲你最好的選擇是將採購訂單數據放入一個單獨的表格中,然後將這兩個數據與FK列聯繫起來。

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

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

問題是當supplierQuoteID記錄被刪除時,父表中的purchaseOrder將無用。因此,我將不得不寫一個觸發器或以此來擦除父購買訂單記錄。我決定通過使用隨機發生器等從前端手動插入PONumber。 – user311509 2010-04-08 16:18:16

+0

如果您想確保PONumbers是唯一的,我不會使用隨機數字生成器。我會使用Guid.NewGuid()。確保數據庫唯一性的兩個最簡單的方法是使用身份或GUID。 – 2010-04-08 16:22:03

+0

您也可以級聯刪除 - 當您刪除supplierQuote時,只要設置刪除級聯到關聯的PurchaseOrder記錄,只要它與任何其他SupplierQuote沒有關聯即可。 – 2010-04-08 16:23:02

2

你不能解決你 - 你每個表只能有一個單獨的IDENTITY列。沒有辦法,對不起。

唯一的「hackish」解決方案是將一個單獨的表格僅僅包含一個INT IDENTITY字段,並且在插入時(例如使用觸發器)從該輔助表格獲取最新值到您的實體中。不是很漂亮,但它可能適合你。

9

如果SupplierQuoteId和採購單號碼生成當行被插入,則兩個「同一性」的列將被以鎖步分配(3504去與9553,3506去與9573,3508去與9593等) 。如果這個假設是真的,那麼你大概可以使採購單號碼計算列,就像這樣:

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

我做supplierQuoteId NOT NULL,這確保了採購單號碼也將NOT NULL。同樣,您不再需要PONumber上的唯一約束,因爲它始終是唯一的。 (如果需要性能指標,可以在計算列上建立索引。)

0

我想我會使用觸發器來填充「第二個標識」。

1

如果每個供應商報價只有一個採購訂單編號,那麼爲什麼不簡單地使用供應商報價編號作爲採購訂單編號?

如果可以有多個,則必須有一個帶有外鍵約束的分離表。當然,您可以使用級聯刪除從此表中刪除,但如果您刪除了太多記錄(導致鎖定)或個人問題,這可能很危險,如果已創建採購訂單編號,我不想刪除供應商報價,因爲這意味着物品報價實際上是買了。你不想破壞實際購買的東西的記錄。由於您可能會有多個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())