2016-03-29 12 views
-1

さて、私は自分のサイトで(Authorize.Net経由で)支払いを受け入れています。支払いフォームは領収書ページにリダイレクトされます。特定の要件を持つデータベーステーブルの最終行を取得するには?

請求書コード(InvoiceCode列)(このインスタンスではRRC0A)の列がデータベースにあります。それから私は8桁の数字(列InvoiceNumber)の別の列を持っています。それからInvoiceCode + InvoiceNumber = InvoiceIdを取得します。たとえば、InvoiceIdはRRC0A + 8の番号になります。 00000000、00000001、00000002などのように増加します。したがって、InvoiceIdはRRC0A00000001になります。また、私は新しい行を追加するとき1でInvoiceNumberをインクリメントする必要が00000000

  1. で開始し、他のInvoiceCodesがあるだろうので、私は単に私のデータベース内の列をインクリメントすることはできません。データベースに入力された最後のInvoiceNumberを取得するにはどうすればよいですか? InvoiceCode RRC0Aに関連付けられている必要があります。これは、1人以上の人が支払いを行っているときに発生する可能性があるため、私は最良の方法についてはわかりません。

  2. どのようにして増分するInvoiceNumberを0の前に付けて、常に8桁にすることができますか?

+0

私はIDフィールドと計算フィールドを提案します。あなたが間違っているように最後に挿入された行を選択しようとしないでください。 –

+1

通常は非常に悪いアイデアは連続したIDを処理して、あなたのdbに1つの自動インクリメントフィールドを作成する方が良い –

+3

自分でインクリメントする数字を管理することは良いアイデアではありません。これは、IDプロパティが処理するように設計されたものです。別のオプションはシーケンスです。これらの両方は並行性のような処理を行い、トランザクションをロールバックすることは非常に難しく、非常に間違いが非常に簡単です。 –

答えて

0
  1. あなたは、SELECTクエリで最後InvoiceNumberをつかむことができます。

  2. 2つの文字列を連結するには、請求記号番号に+記号をつけて、右端の8文字を入力するにはRIGHT()を使用します。

+0

に一意のインデックスをスローするようにしてください。Scope_Identity()とプライマリキーを使用しない限り、これを行わないでください。 –

+0

Scope_identityは、SELECTが最新のINSERTと同じクエリコンテキストで発生した場合にのみ有効です。 –

+0

あなたは、インサートからアイデアを得ることができない場合は、正しい請求書を取得することは保証されません。最後の行を選択しただけでは、リクエスト前に別の請求書が挿入されている可能性があります。 –

1
SELECT InvoiceCode, MAX(InvoiceID) 
    FROM yourTable t 
    GROUP BY InvoiceCode 

これは、各InvoiceCodeの最新InvoiceIDを返す必要がありますが、あなたは追加することができ、あなた自身の句は、SQLのパッド左方法については

それを絞り込むこのanswerをチェックアウトするWHERE 。

+0

これはうまくいく可能性があります。 2人で同時に決済フォームに記入するとどうなるのでしょうか? – RockOn

+0

この状況では、SQLクエリ自体は安全です。選択が実行されている間にテーブルの読み取りロックが失われ、更新が妨げられます。あなたはまだストリームを通ってより離れて同期データの問題に対処する必要があります。 – Wizwert

+0

これは、あなたがInvoiceCode – Paparazzi

1

1列のようにAがちょうど悪いデザインです

は、複合PK
InvCode(varchar型)を持つInvInt(int型)

declare @InvCode varchar(20) = 'RRC0A' 
insert into invoice (InvCode, InvInt) 
OUTPUT INSERTED.InvInt, INSERTED.InvCode 
select @InvCode, isnull(max(InvInt),-1) + 1 
    from invoice 
    where InvCode = @InvCode; 

ISNULLは、最初の1

に対処します

1つの文がトランザクションなので、2つの同時実行が同時に起こるとは思わない
PKを実行しても挿入が失敗するように違反する可能性があります

利用IDを使用してフォーマットされた請求書番号

CREATE TABLE [dbo].[Invoice](
    [InvCode] [varchar](10) NOT NULL, 
    [InvInt] [int] NOT NULL, 
    [Formatted] AS ([InvCode]+right('00000000'+CONVERT([nvarchar](10),[InvInt]),(8))), 
CONSTRAINT [PK_Invoice] PRIMARY KEY CLUSTERED 
(
    [InvCode] ASC, 
    [InvInt] ASC 
) 
+0

を試してみることを考えると、不必要な読み取りロックとMAX(InvoiceID)の数だけです。私はこれが私のために働くと思う。 – RockOn

2

、あなたが挿入時に正しい書式で数字を請求することができます作成​​した計算列のためのビューまたは計算列。

CREATE TABLE [dbo].[Invoices](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Code] [nchar](5) NOT NULL, 
    [InvoiceNumber] AS ([Code]+right('00000000'+CONVERT([nvarchar](10),[ID]),(8))) PERSISTED, 
    [Cost] [decimal](18, 2) NOT NULL, 
    CONSTRAINT [PK_Invoices] PRIMARY KEY CLUSTERED 
    (
     [ID] ASC 
    ) 
) 

サンプル一括挿入

INSERT INTO [dbo].[Invoices] ([Code], [Cost]) 
OUTPUT INSERTED.* 
SELECT 'ABC01', 500 UNION ALL 
SELECT 'ABC01', 501 UNION ALL 
SELECT 'EFG23', 502 UNION ALL 
SELECT 'RRAc1', 503 UNION ALL 
SELECT 'ABC01', 504 

出力

ID Code InvoiceNumber Cost 
1 ABC01 ABC0100000001 500.00 
2 ABC01 ABC0100000002 501.00 
3 EFG23 EFG2300000003 502.00 
4 RRAc1 RRAc100000004 503.00 
5 ABC01 ABC0100000005 504.00 

あなたのレコードを挿入するとき、あなたが戻って同時にIDとInvoiceNumberを得ることができます。

値は永続化され、他の列と同じように索引付けされます。

+1

"00000000から始まる他のInvoiceCodeが存在するため、データベースの列を単純にインクリメントすることはできません"。私の理解では、OPは各請求書コードに対して0で始まる請求書番号を望んでいます。 – Paparazzi

+0

はい、正しいです。このコードを使用すると、InvoiceCodeごとにテーブルを作成する必要があります。今すぐに数十のInvoiceCodeがあり、時間内にのみ展開されます。 – RockOn

+0

あなたはグループの更新で行を上にすることができますが、私はそれをお勧めしません。プレフィックスを必要なコードに置き換えるだけで、アイデンティティにインボイス番号を付加するほうがずっと良いでしょう。後で更新を外部化しようとすると、値を同期させておくことで、より多くの問題にぶつかります。 (接頭辞をテーブル内の別の列に簡単に移動して、計算された値の一部として使用できます。そのコードを取得するためにジョイントのような操作を行うと、永続化された値を使用できなくなります。 –

関連する問題