需要非常简单的'序列'用于SQL Server的GetNextOrderNumber

时间:2009-11-29 10:06:03

标签: sql sql-server sequence

我正在尝试制作比one described here更简单的功能,以获取购物车订单号的下一个值。

  • 我不在乎是否有空白
  • 只有已完成的订单才能获得ID(即我故意不使用IDENTITY)
  • 显然一定不能有重复
  • 我不关心性能和锁定。如果我们有这么多新订单,我关心lockin那么我会先遇到其他问题

我发现了很多其他类似的问题,但不是我正在寻找的确切解决方案。

到目前为止我所拥有的是:

USE [ShoppingCart]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sequence_CompletedOrderID]
([val] [int] NOT NULL 
  CONSTRAINT [DF_Sequence_CompletedOrderID_NextValue]  DEFAULT ((520000))
) ON [PRIMARY]

然后是存储过程:

CREATE PROC dbo.GetNextCompletedOrderId 
  @nextval AS INT OUTPUT
AS

UPDATE dbo.sequence_completedorderid SET @nextval=val += 1;
GO

就像我说的那样,我试图将它基于我上面链接的文章 - 所以也许这只是一种笨拙的方式。对于像这样的简单事情,以及过去的睡觉时间,我的SQL并不是很重要。谢谢!

5 个答案:

答案 0 :(得分:1)

好的,所以你的主表中已经有了一个IDENTITY列 - 但是如果只有一个额外的表又有一个IDENTITY列?这样可以省去麻烦和麻烦......

USE [ShoppingCart]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sequence_CompletedOrderID]
([val] [int] NOT NULL IDENTITY(520000, 1)
) ON [PRIMARY]



CREATE PROC dbo.GetNextCompletedOrderId 
  @nextval AS INT OUTPUT
AS
   INSERT INTO dbo.Sequence_CompletedOrderID DEFAULT VALUES

   SELECT @nextval = SCOPE_IDENTITY()
GO

这样,您可以放弃确保SQL Server独有的所有麻烦,并确保您不会从IDENTITY列中获得两次相同的值!

答案 1 :(得分:1)

@marc_s的解决方案为每个生成的数字创建一个新行。起初我不认为我喜欢这个,但意识到我可以利用它来发挥我的优势。

我所做的是在存储过程中添加了日期时间审计列和@orderid参数。对于特定的orderid,它将保证返回相同的completedorderid,这是序列生成器中的数字。

如果由于某种原因,我的应用程序层请求下一个id,但在它可以提交事务之前崩溃 - 它仍将链接到该命令,以便在再次请求时将返回相同的数字。

这就是我最终的结果:

USE [ShoppingCart]
GO
/****** Object:  Table [dbo].[Sequence_CompletedOrderID]    Script Date: 11/29/2009 03:36:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sequence_CompletedOrderID](
    [val] [int] IDENTITY(520000,1) NOT NULL,
    [CreateDt] [datetime] NOT NULL CONSTRAINT [DF_Sequence_CompletedOrderID_CreateDt]  DEFAULT (getdate()),
    [Orderid] [int] NOT NULL CONSTRAINT [DF_Sequence_CompletedOrderID_Orderid]  DEFAULT ((0)),
 CONSTRAINT [PK_Sequence_CompletedOrderID] PRIMARY KEY CLUSTERED 
(
    [Orderid] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]


USE [ShoppingCart]
GO
/****** Object:  StoredProcedure [dbo].[GetCompletedOrderId]    Script Date: 11/29/2009 03:34:08 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[GetCompletedOrderId] 
  @orderid AS INT,
  @completedorderid AS INT OUTPUT
AS

IF EXISTS (SELECT * FROM dbo.Sequence_CompletedOrderID WHERE orderid = @orderid)
BEGIN 
    SET @completedorderid =(SELECT val FROM dbo.Sequence_CompletedOrderID WHERE orderid = @orderid)
END 
ELSE
BEGIN
   INSERT INTO dbo.Sequence_CompletedOrderID (orderid) VALUES (@orderid)
   SET @completedorderid =(SELECT SCOPE_IDENTITY())
END

答案 2 :(得分:1)

如果您使用Sequence_CompletedOrderID表作为订单ID的一行表,那么您应该使用UPDATE并依靠OUTPUT clause来捕获新值:

CREATE PROC dbo.GetNextCompletedOrderId 
  @nextval AS INT OUTPUT
AS
SET NOCOUNT ON;
UPDATE dbo.Sequence_CompletedOrderID
SET val=val + 1
OUTPUT @nextval = INSERTED.val;
GO

答案 3 :(得分:0)

在表格中插入数据后如何使用以下语句?

UPDATE dbo.sequence_completedorderid
SET @nextval = (SELECT MAX(val) + 1 FROM dbo.sequence_completedorderid)

答案 4 :(得分:0)

您不需要新的id列,只需添加一个新的OrderCompleted列(位),并将其与您已有的ID相结合。

SELECT Id FROM T_Order WHERE OrderCompleted = 1