Вот мои предложения:
Ваша таблица должна выглядеть как
CREATE TABLE COUPONS
(COUPON_CODE NUMBER
CONSTRAINT PK_COUPONS
PRIMARY KEY
USING INDEX); -- plus whatever other fields you need
Ваш код, чтобы генерировать уникальные коды должны быть что-то вроде
DECLARE
nCoupon_code NUMBER;
bCode_unique BOOLEAN;
BEGIN
bCode_unique := FALSE;
WHILE bCode_unique = FALSE LOOP
BEGIN
nCoupon_code := GENERATE_COUPON_CODE; -- function to generate a coupon code
INSERT INTO COUPONS (COUPON_CODE)
VALUES (nCoupon_code);
bCode_unique := TRUE;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
NULL; -- Fall through, loop back to the top, generate new code, continue
END;
END LOOP; -- bCode_unique
END;
Что здесь является то, что программа сначала установите флаг «code unique» в FALSE, указывая, что уникальный код еще не создан. Затем вводится цикл и будет продолжаться до тех пор, пока флаг «code unique» по-прежнему будет FALSE. Затем генерируется и сохраняется код купона в базе данных. Если код уникален, все будет хорошо, будет установлен флаг «уникальный код», и цикл будет завершен. ОДНАКО, если код НЕ уникален, инструкция INSERT терпит неудачу с исключением DUP_VAL_ON_INDEX. Это произойдет потому, что COUPON_CODE является основным ключом в таблице COUPONS, и мы знаем, что первичный ключ имеет три атрибута: он должен быть не-NULL, если он никогда не должен изменяться, и он ДОЛЖЕН БЫТЬ УНИКАЛЬНЫМ. (Для наших целей здесь мы могли бы использовать ограничение UNIQUE для COUPONS.COUPON_CODE и получили тот же эффект).Если исключается исключение DUP_VAL_ON_INDEX, потому что генерируемый код купона не уникален, обработчик исключений будет введен, где код ничего не сделает; то есть флаг «code unique» останется FALSE, код будет выпадать из обработчика исключений, а поскольку флаг «уникальный код» по-прежнему FALSE, цикл начнется снова, когда будет сгенерирован другой код, и т. д. etc и т. д., пока не будет создан уникальный код и INSERT удастся.
Это может показаться большой работой, но если алгоритм генерации кода купона выбран хорошо, он не будет генерировать много столкновений и, следовательно, не будет слишком часто чередоваться. ИМО это разумное решение с учетом окружающей среды - в PL/SQL вы рассчитываете использовать базу данных для выполнения некоторых тяжелых операций, таких как гарантия уникальности. Вы можете потратить много времени, пытаясь придумать алгоритм генерации одного True кода, который никогда не будет когда-либо генерировать дубликат, или вы можете просто придумать что-то хорошее, если не совершенное и работать с базой данных, чтобы убедитесь, что коды, которые окончательно выбраны, становятся уникальными. YMMV. И реализация One True Algorithm может быть очень забавной, если не особенно хорошо использовать время. :-)
Делитесь и наслаждайтесь.
код купона хранится в db? – Lokesh
не может просто создать последовательность и использовать порядковый номер в качестве кода купона? – Lokesh
@loki: Мне нужно сгенерировать коды купе с последовательностями, которые можно легко угадать. Поэтому любой может попробовать со следующим номером и пропустить коды купонов. Последовательность не является решением. –