0

私はmysql/phpを使用しています。

私のテーブルは

id (int autoincrement)  
voucher(varchar 25)

コードが次の場合にバウチャーコードを生成しています:

  • 1つの乱数(例:64)
  • 1つの固定番号(例:352)
  • idフィールドの値(1,2,3,4,5 ...)
  • 1チェックディジット(luhnアルゴリズム)。

phpでこれを行う際の明らかな問題は、選択を実行し、次の自動インクリメント値を取得し、コードを計算し、挿入する必要があることです。その時点で、別の行が挿入されている可能性があります。

私がやりたいのは代わりに、

insert into vouchers (voucher) value('64352')て、それが私の残りの部分を生成するようにします。

これどうやってするの?機能/トリガー?

4

2 に答える 2

1

InnoDBを使用している場合、簡単な修正は、既存のコードを使用して、それをMySQLトランザクションでラップすることです。すなわち、擬似コードで:

mysql_query("START TRANSACTION");

# get next autoincrement value into: $next

# do your INSERT query

# get the actual last inserted ID into: $actual

if ($next === $actual) {
  mysql_query("COMMIT");
} else {
  mysql_query("ROLLBACK");
  # and raise an Exception or return an error
}

編集/追加:

あなたがトリガーについて言及したので、私はそれを調べて、それが実行可能であると信じています。いくつかの問題。

  1. トリガーから「次の自動インクリメントID」にアクセスする...これを行うための「良い」方法がわかりません。INSERTクエリでは、NEW(既存の行)の値にはアクセスでき、OLD(既存の行)の値にはアクセスできません(トリガー構文を参照)。この例で私がしていることは、サーバー上に別個のカウンター@vcountを維持することです。この値を現在のIDに初期化するには、「SET @vcount=42;」を実行するだけです。

  2. Luhnアルゴリズム。これをSQL関数として実装する必要があります。これがSQLのLuhnバリデーターです。または、MD5などのネイティブMySQL関数を使用してハッシュ/チェックサムを実行することもできます(短いバウチャーコードが必要な場合は、最初のX文字のみを使用します)。いずれにせよ、ハッシュ関数を作成する必要があります...以下の「Luhn」を使用します。

とにかく、トリガーは次のようになります。

delimiter //
CREATE TRIGGER make_voucher_code BEFORE INSERT ON vouchers
FOR EACH ROW
BEGIN
    SET @vcount = @vcount + 1;
    SET NEW.voucher = CONCAT(
        NEW.voucher, 
        CAST(@vcount AS CHAR),
        Luhn(CONCAT(NEW.voucher, CAST(@vcount AS CHAR))));
END;
//
delimeter ;

次に、INSERTで、提案したように、クエリに「64352」だけを入力します。トリガーは残りを追加します。

個人的には、あなたや他の誰かがautoincrement / @ vcountの問題をよりよく解決できない限り、MySQLトランザクションを実行することをお勧めします。これは、すべてをアトミックに保ち、すべてのアプリコードをPHPで保持するよりも優れた仕事をします。

于 2011-05-12T01:00:01.457 に答える
0

または、値0で挿入を実行してから、挿入IDを取得し、値を計算して、でレコードを更新します。

于 2011-05-12T01:02:54.957 に答える