我正在尝试制作比one described here更简单的功能,以获取购物车订单号的下一个值。
我发现了很多其他类似的问题,但不是我正在寻找的确切解决方案。
到目前为止我所拥有的是:
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并不是很重要。谢谢!
答案 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