1

我正在尝试制作一个比这里描述的更简单的函数来获取购物车订单号的下一个值。

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

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

我到目前为止是这样的:

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 也不太好用,而且它已经过了我的就寝时间。谢谢!

4

5 回答 5

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 列中获得两次相同的值!

于 2009-11-29T10:24:08.683 回答
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
于 2009-11-29T11:39:07.143 回答
1

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

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
于 2009-11-29T18:19:02.463 回答
0

在表中插入数据后使用以下语句怎么样?

UPDATE dbo.sequence_completedorderid
SET @nextval = (SELECT MAX(val) + 1 FROM dbo.sequence_completedorderid)
于 2009-11-29T10:17:53.503 回答
0

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

SELECT Id FROM T_Order WHERE OrderCompleted = 1
于 2009-11-29T10:29:36.897 回答