ここに私の提案があります:
テーブルは次のようになります
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;
ここで何が起こっているかというと、プログラムは最初に「一意のコード」フラグを FALSE に設定し、一意のコードがまだ生成されていないことを示しています。その後、ループに入り、'code unique' フラグがまだ FALSE である限り継続します。次に、クーポン コードが生成され、データベースに保存されます。コードが一意である場合、すべて問題なく、「一意のコード」フラグが設定され、ループが終了します。ただし、コードが一意でない場合、INSERT ステートメントは DUP_VAL_ON_INDEX 例外で失敗します。これは COUPON_CODE が COUPONS テーブルの主キーであり、主キーには 3 つの属性があることがわかっているためです。(ここでの目的のために、COUPONS.COUPON_CODE に UNIQUE 制約を使用して、同じ効果を得ることもできます)。生成されたクーポン コードが一意ではないために DUP_VAL_ON_INDEX 例外がスローされた場合、コードがまったく何もしない例外ハンドラーに入ります。つまり、'code unique' フラグは FALSE のままで、コードは例外ハンドラーから脱落し、'code unique' フラグがまだ FALSE であるため、別のコードが生成される場所でループが再び開始されます。などなど、一意のコードが最終的に生成され、INSERT が成功するまで。
これは大変な作業のように思えるかもしれませんが、クーポン コード生成アルゴリズムが適切に選択されていれば、多くの衝突は発生しないため、頻繁にループする必要はありません。IMO これは、環境を考慮すると合理的な解決策です。PL/SQL では、データベースを使用して、一意性の保証などの面倒な作業を行うことを期待しています。重複を生成することは決してなく、おそらく重複を生成しない唯一の真のコード生成アルゴリズムを考え出すために膨大な時間を費やすことができます。最終的に選択されたコードが一意になるようにしてください。YMMV。また、One True Algorithm の実装は、特に有効な時間の使い方ではないにしても、非常に楽しいものです。:-)
共有してお楽しみください。