Нужна очень простая "последовательность" для GetNextOrderNumber для SQL Server
-
06-07-2019 - |
Вопрос
Я пытаюсь создать еще более простую функцию, чем один из них описан здесь чтобы получить следующее значение номера заказа для корзины покупок.
- Меня не волнует, есть ли пробелы
- Только выполненные заказы получают идентификатор (т.е.Я намеренно не использую ИДЕНТИФИКАЦИЮ)
- Очевидно, что дубликатов быть не должно
- Меня не волнует производительность и блокировка.Если у нас будет так много новых заказов, о которых я забочусь, то сначала у меня возникнут другие проблемы
Я нашел довольно много других подобных вопросов, но не то точное решение, которое я ищу.
То, что у меня есть на данный момент, это :
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 не совсем подходит даже для таких простых вещей, как эта, и мне давно пора спать.Спасибо!
Решение
Хорошо, итак, у вас уже есть столбец 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!
Другие советы
Если вы используете Sequence_CompletedOrderID
таблица в виде однострочной таблицы идентификаторов заказов, то вам следует использовать UPDATE и полагаться на Предложение ВЫВОДА чтобы зафиксировать новое значение:
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
Решение от @marc_s создает новую строку для каждого сгенерированного числа.Сначала я не думал, что мне это нравится, но понял, что могу использовать это в своих интересах.
Что я сделал, так это добавил столбец аудита даты и времени, а также параметр @orderid в сохраненный процесс.Для конкретного orderid
это гарантированно вернет то же самое completedorderid
, которое является числом из генератора последовательностей.
Если по какой-то причине мой прикладной уровень запрашивает следующий идентификатор, но затем происходит сбой до того, как он сможет зафиксировать транзакцию - он все равно будет связан с этим заказом, так что при повторном запросе будет возвращен тот же номер.
Это то, с чем я в итоге столкнулся:
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
Как насчет использования следующего оператора после вставки данных в вашу таблицу?
UPDATE dbo.sequence_completedorderid
SET @nextval = (SELECT MAX(val) + 1 FROM dbo.sequence_completedorderid)
Вам не нужен новый столбец id, все, что вам нужно, это добавить новый столбец OrderCompleted (бит) и объединить его с идентификатором, который у вас уже есть.
SELECT Id FROM T_Order WHERE OrderCompleted = 1