Нужна очень простая «последовательность» для GetNextOrderNumber для SQL Server - PullRequest
1 голос
/ 29 ноября 2009

Я пытаюсь сделать еще более простую функцию, чем описанная здесь , чтобы получить следующее значение номера заказа для корзины.

  • Мне все равно, есть ли пробелы
  • Только выполненные заказы получают идентификатор (т. Е. Я сознательно не использую 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 не совсем подходит даже для таких простых вещей, как эта, и он уже давно не спит. Спасибо!

Ответы [ 5 ]

1 голос
/ 29 ноября 2009

Если вы используете таблицу Sequence_CompletedOrderID в качестве таблицы строк с идентификаторами заказов, вам следует использовать 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
1 голос
/ 29 ноября 2009

Решение от @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
1 голос
/ 29 ноября 2009

ОК, значит, у вас уже есть столбец 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!

0 голосов
/ 29 ноября 2009

Вам не нужен новый столбец идентификатора, все, что вам нужно, это добавить новый столбец OrderCompleted (бит) и объединить его с уже имеющимся идентификатором.

SELECT Id FROM T_Order WHERE OrderCompleted = 1
0 голосов
/ 29 ноября 2009

Как насчет использования следующего оператора после вставки данных в вашу таблицу?

UPDATE dbo.sequence_completedorderid
SET @nextval = (SELECT MAX(val) + 1 FROM dbo.sequence_completedorderid)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...