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

Sequence_CompletedOrderIDテーブルを注文 ID の 1 行のテーブルとして使用する場合は、 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 に答える
1

OK、メイン テーブルには既に 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 列から同じ値が 2 回返されることもありません。

于 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 に答える
0

新しい id 列は必要ありません。必要なのは、新しい OrderCompleted 列 (ビット) を追加し、それを既に持っている id と結合することだけです。

SELECT Id FROM T_Order WHERE OrderCompleted = 1
于 2009-11-29T10:29:36.897 に答える
0

テーブルにデータを挿入した後、次のステートメントを使用するのはどうですか?

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