我正在尝试插入已建立的表,该表具有主键字段和另一个唯一的字段(称为field1)(此另一个唯一字段具有阻止我的插入的唯一约束)。 Field1不是标识字段,因此它不会自动编号。不幸的是我不能改变桌子。现有插入使用代码进行递增,并且所有插入都涉及循环/游标。像SELECT MAX(field1)+ 1
这样的东西那么,无论如何在没有循环/游标的情况下执行此插入操作?这个字段对我来说没有任何意义,但是已经有500,000多条记录使用了他们愚蠢的编号方案,所以我必须尊重它。
这是简化的(ReceiptNumber是我想要插入唯一的字段),但是:
SET XACT_ABORT ON
Begin Transaction TransMain
Declare @nvErrMsg nvarchar(4000)
--Insert inventory receipts
Insert Into Avanti_InventoryReceipts (
ReceiptNumber , ItemNumber , ReceiptDate , OrderNumber , JobNumber , Supplier ,
LineNumber , MultiLineNumber , [Status] , QtyOrdered , QtyReceived , QtyToReceive ,
QtyBackOrdered , Cost , Wholesale , LastCost , QtyToInvoice , QtyUsed ,
ReferenceNumber , [Description] , SupplierType , Processed , DateExpected , DateReceived ,
AccountNumber , Reference2 , EmployeeCode , ExtraCode , Location , RollNumber ,
QtyIssues , Notes , NumPackages , BundleSize , ConsignmentUnitPrice , RecFromProduction ,
QtyCommitted )
SELECT ( SELECT MAX(ReceiptNumber) + 1 FROM Avanti_inventoryReceipts ) , CR.ItemNumber , Convert(char(8), GETDATE(), 112) , PONum , 'FL-INV' , PH.POVendor ,
0 , 0 , 'O' , CR.QtyOrdered , QtyReceivedToday , QtyReceivedToday ,
Case @closePO
When 'N' Then Case When ( QtyOrdered - QtyReceivedToday ) < 0 Then 0 Else ( QtyOrdered - QtyReceivedToday) End
When 'Y' Then 0
Else 0 End
, PD.TransCost * QtyReceivedToday , IH.PriceWholeSale , IH.CostLast , QtyReceivedToday , 0 ,
'' , PODetailDescription , '' , '' , '' , Convert(char(8), GETDATE(), 112) ,
'' , '' , @employeeCode , '' , 'F L E X O' , '' ,
0 , 'Flexo Materials' , 0 , 0 , 0 , '' , 0
FROM FI_CurrentReceiptData CR
LEFT JOIN Avanti_PODetails PD ON CR.PONum = PD.PONumber
LEFT JOIN Avanti_POHeader PH ON CR.PONum = PH.PONumber
LEFT JOIN Avanti_InventoryHeader IH ON CR.ItemNumber = IH.ItemNumber
IF @@ERROR <> 0
Begin
Select @nvErrMsg = 'Error entering into [InventoryReceipts] -' + [description]
From master..sysmessages
Where [error] = @@ERROR
RAISERROR ( @nvErrMsg , 16, 1 )
Goto Err_
End
Commit Transaction TransMain
Goto Exit_
Err_:
Rollback Transaction TransMain
Exit_:
SET XACT_ABORT OFF
答案 0 :(得分:0)
你可以这样做:
insert into mytable (field1, field2, ...)
values (( SELECT MAX(field1) + 1 from mytable), 'value2', ...);
答案 1 :(得分:0)
为什么不循环?它应该非常有效。
由于您已在该字段上拥有UNIQUE约束,您可以:
MAX(field1) + 1
即可。由于UNIQUE字段上有索引,MAX
很快。大多数情况下,INSERT会立即成功。在并发用户尝试插入相同值的极少数情况下,您可以通过尝试“下一个”值来优雅地处理它。
答案 2 :(得分:0)
我在客户端代码中添加了一个从0开始的自动编号并将其传入。现在我将该值添加到最大收据数以获得唯一的值。此外,我意识到我已经在FI_CurrentReceiptData中有一个标识列,但我不想使用它,因为它不会从每个收据集的0开始,并且每次重新播种标识似乎浪费了处理器时间。