Один очень удобный встроенный тип данных для генерации уникальных кодов, которые трудно угадать, - это тип данных uniqueidentifier
. Вы можете использовать это для генерации уникального кода, придав ему автоматически генерируемое значение (используя функцию newid ()). Поскольку идентификаторы GUID находятся в HEX и не генерируются последовательно в отличие от столбцов идентификаторов, невозможно предсказать, какие коды будут созданы или будут сгенерированы, что сделает ваш процесс менее уязвимым для тех, кто просто пытается кодировать последовательно. Количество возможных уникальных идентификаторов очень велико.
Я сделал предположение, что для каждой вашей акции вам понадобится только один промо-код на человека. Вы можете сделать это в своей базе данных, имея таблицу, в моем примере она называется PromoTest, у которой есть первичный ключ в обоих столбцах, что гарантирует их уникальность. Я не добавил понятие «Используется», чтобы указать, использовал ли человек этот код, но это довольно тривиально.
Чтобы создать таблицу с ограничением первичного ключа и автоматически сгенерированным значением, выполните следующее:
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]
Иметь хранимую процедуру, которая вставляет новый промо-код или выбирает существующий, довольно тривиально, и из-за ограничения первичного ключа вы не можете физически вставить два кода одного типа для одного и того же человека.
Хранимая процедура может быть определена следующим образом:
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