تحتاج إلى "تسلسل" بسيط جدًا لـ GetNextOrderNumber لـ SQL Server

StackOverflow https://stackoverflow.com/questions/1815145

  •  06-07-2019
  •  | 
  •  

سؤال

أحاول أن أقوم بوظيفة أبسط من واحد موصوف هنا للحصول على القيمة التالية لرقم الطلب لعربة التسوق.

  • لا يهمني إذا كانت هناك ثغرات
  • الطلبات المكتملة فقط هي التي تحصل على معرف (أي.أنا لا أستخدم 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]

ثم من أجل proc المخزن:

CREATE PROC dbo.GetNextCompletedOrderId 
  @nextval AS INT OUTPUT
AS

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

كما قلت، أحاول أن أبني ذلك على المقالة التي قمت بربطها أعلاه - لذا ربما تكون هذه مجرد طريقة خرقاء للقيام بذلك.SQL الخاص بي لا يصل إلى حد كبير حتى بالنسبة لأشياء بسيطة مثل هذه، وقد تجاوز وقت نومي.شكرًا!

هل كانت مفيدة؟

المحلول

حسنًا، لديك بالفعل عمود هوية في جدولك الرئيسي - ولكن ماذا عن مجرد وجود جدول إضافي يحتوي مرة أخرى على عمود هوية؟؟وهذا سيوفر عليك الكثير من المتاعب والمتاعب .....

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، وسيتأكد أيضًا من أنك لن تستعيد نفس القيمة مرتين من عمود الهوية!

نصائح أخرى

إذا كنت تستخدم 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)

لا تحتاج إلى عمود معرف جديد، كل ما تحتاجه هو إضافة عمود OrderCompleted جديد (بت)، ودمج ذلك مع المعرف الذي لديك بالفعل.

SELECT Id FROM T_Order WHERE OrderCompleted = 1
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top