Un type de données intégré très pratique pour générer des codes uniques difficilement concevables est le type de données uniqueidentifier
. Vous pouvez l'utiliser pour générer un code unique en lui donnant une valeur générée automatiquement (en utilisant la fonction newid()). Parce que les GUID sont dans HEX et ne sont pas générés séquentiellement contrairement aux colonnes d'identité, il n'est pas possible de prédire quels codes ont été ou seront générés, ce qui rendra votre processus moins vulnérable à quelqu'un qui essaie les codes en séquence. Le nombre d'identifiants uniques possibles est très important.
J'ai supposé que vous ne souhaitiez qu'un seul code promotionnel par personne pour chacune de vos promotions. La façon dont vous pouvez faire cela dans votre base de données est d'avoir une table, mon exemple l'appelle PromoTest, qui a une clé primaire sur ces deux colonnes, ce qui garantit qu'elles restent uniques. Je n'ai pas ajouté un concept de 'Utilisé' pour indiquer si la personne a utilisé le code mais c'est assez trivial à faire.
Pour créer votre table avec la contrainte de clé primaire et la valeur exécutez la commande suivante généré automatiquement:
CREATE TABLE [dbo].[PromoTest](
[personid] [bigint] NOT NULL, [promocategory] [int] NOT NULL,
[promocode] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_PromoTest] PRIMARY KEY CLUSTERED (
[personid] ASC,
[promocategory] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS
= ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]
GO
ALTER TABLE [dbo].[PromoTest] ADD CONSTRAINT [DF_PromoTest_promocode] DEFAULT (newid()) FOR [promocode]
Pour avoir ensuite une procédure stockée qui insère un nouveau code promo ou sélectionne l'existant est tout à fait trivial , et en raison de la contrainte de clé primaire, vous ne pouvez pas insérer physiquement deux codes du même type pour la même personne.
La procédure stockée peut être définie comme suit:
CREATE PROCEDURE GetOrCreatePromoCode
-- Add the parameters for the stored procedure here
@PersonId bigint,
@PromoCategory int,
@PromoCode uniqueidentifier OUT
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF (NOT EXISTS(SELECT PromoCode FROM PromoTest WHERE personid = @PersonId AND promocategory = @PromoCategory))
BEGIN
INSERT INTO PromoTest (personid, promocategory) VALUES (@PersonId, @PromoCategory)
END
SET @PromoCode = (SELECT PromoCode FROM PromoTest WHERE personid = @PersonId AND promocategory = @PromoCategory)
END
GO