2010-12-10 23 views
0

J'incrémente la valeur alphanumérique de 1 pour le produit en utilisant la procédure stockée. Ma procédure incrémentant les valeurs jusqu'à 10 enregistrements, une fois qu'il atteint 10e dire pour PRD0010 ... pas plus son incrémentation ... Cependant, le problème est qu'il répète les mêmes valeurs PRD0010 .. pour chaque appel SP.Pourquoi la génération d'ID naturelle dans ce processus stocké SQL crée-t-elle des doublons?

Quelle est la cause de ceci?

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 

Répondre

3

changement

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

Pour

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

Vous devez vous rappeler que

PRD009 

est toujours supérieure à

PRD0010 

ou

PRD001 

Dans l'ensemble, je pense que votre approche est incorrecte.

Vos valeurs seront

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

Cela fera le tri d'un cauchemar.

+0

astander-> exactement vous avez raison ... ses fine..thanks travail ur réponse – Jims

+1

Un autre problème est que cette technique ne produira pas des identifiants uniques avec insertions concurrentes. –

0

Outre l'analyse d'astander, vous avez également un problème de simultanéité.

La solution simple serait d'ajouter ceci au début de votre proc:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
BEGIN TRANSACTION 

Et ajouter un COMMIT à la fin. Autrement, deux appelants de ce proc stocké recevront la même valeur MAX/TOP 1 de votre table, et insèreront la même valeur.

De même, vous pouvez et devez empêcher l'existence de ces doublons en ajoutant une clé à votre table pour cette colonne. Si vous avez déjà une PRIMARY KEY sur cette table, vous pouvez ajouter une clé supplémentaire en utilisant une contrainte UNIQUE. Cela empêchera les doublons à l'avenir, quelles que soient les erreurs de programmation. Par exemple.

ALTER TABLE tblProduct ADD CONSTRAINT UQ_Product_ID UNIQUE (ID)