2010-12-10 9 views
0

ストアドプロシージャを使用するproductidの英数字の値を1増やしています。私の手続きでは、10レコードまでの値をインクリメントして、10に達するとPRD0010と言っています...それ以上のインクリメントはありません...しかし、問題は、 と同じ値のPRD0010 ..を各SP呼び出しに対して繰り返しています。このSQLストアドプロシージャで、重複したIDを生成しているのはなぜですか?

この原因は何ですか?

SELECT TOP 1 
     @NId = cast(substring(id, 4, len(id)) as int) 
FROM tblProduct order by LEN(id) DESC, ID DESC 

create table tblProduct 
(
     id varchar(15) 
) 

insert into tblProduct(id)values('PRD00') 

create procedure spInsertInProduct 
AS 
Begin 

    DECLARE @PId VARCHAR(15) 
    DECLARE @NId INT 
    DECLARE @COUNTER INT 
    SET @PId = 'PRD00' 
    SET @COUNTER = 0 
    SELECT @NId = cast(substring(MAX(id), 4, len(MAX(id))) as int) 
    FROM tblProduct group by left(id, 3) order by left(id, 3) 
    --here increse the vlaue to numeric id by 1 
    SET @NId = @NId + 1 
    --GENERATE ACTUAL APHANUMERIC ID HERE 
    SET @PId = @PId + cast(@NId AS VARCHAR) 
    INSERT INTO tblProduct(id)values (@PId) 

END 

答えて

3

変更

SELECT @NId = cast(substring(MAX(id), 4, len(MAX(id))) as int) 
    FROM tblProduct group by left(id, 3) order by left(id, 3) 

あなたは

PRD009 

は常に

以上であることを忘れてはいけませんすべてのすべてで
PRD0010 

または

PRD001 

、私はあなたのアプローチが間違っていると思います。

あなたの値は、これは完全な悪夢をソートするようになります

PRD00 
PRD001 
... 
PRD009 
PRD0010 
PRD0011 
... 
PRD0099 
PRD00100 

になります。

+0

astander->正確にあなたが正しいです...ウル返事 – Jims

+1

のためにその作業fine..thanksは、追加の問題は、この技術は、同時挿入して固有のIDを生成しないということです。 –

0

アナタの分析に加えて、並行性の問題もあります。

簡単な修正は、あなたのPROCの先頭にこれを追加することです:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
BEGIN TRANSACTION 

そして最後にCOMMITを追加します。それ以外の場合、このストアドプロシージャの2人の呼び出し元は、テーブルから同じMAX/TOP 1値を取得し、同じ値を挿入します。

また、この列のキーをテーブルに追加することで、これらの重複が存在しないようにすることもできます。この表にすでにPRIMARY KEYがある場合は、UNIQUE制約を使用して追加のキーを追加できます。これにより、プログラミングエラーが発生した場合でも、重複が将来発生するのを防ぐことができます。例えば。

ALTER TABLE tblProduct ADD CONSTRAINT UQ_Product_ID UNIQUE (ID) 
関連する問題