私が求めているものと同様のトピックをいくつか読みましたが、どれも私にとってあまり役に立たないようです。
Unique 制約を持つ列に格納されるコードをユーザーが生成できるフォームがあります。コードは 7 文字の長さの文字列です。ユーザーが数字を入力すると、プログラムはその数のコードを生成し、コードの最大数に達するまでこれを繰り返すことができます。
私の問題は、値が重複していることです。しかし、新しいエントリを入力する瞬間にデータベースにすでに存在する値ではありません(私はそれらを正常にチェックします)が、コードの新しいグループ(たとえば10000)のエントリの一部は(おそらく)同一です。したがって、私のコードは同じトランザクションで 2 つ (またはそれ以上) の同一のコードを生成し、DB の Unique 制約がそれについて文句を言います。
エントリごとにデータベースをチェックすることを考えましたが、10000 またはそれ以上のエントリについて話していることを考えると、非常に時間がかかります。
したがって、唯一のオプションは、最初にそれらを生成するコードを変更することだと思います。これは、非効率的で double を生成するように思われるためです。
問題の大部分は必要なコードの長さです。それ以外の場合は、純粋な 'uniqid()' または同様のものを使用しますが、7 文字に制限する必要があるため、さらに悪化すると思います。また、コードの一部の文字 ['problem_characters'] をコードから除外する必要があります。
これがコードです。一意の値のみを生成するように適切に変更できませんでした。
$problem_characters = array("0", "o", "O", "I", "1", 1);
$code = md5(uniqid(rand(), true));
$extId = strtoupper(str_replace($problem_characters,rand(2,9),substr($code, 0, 7)));
//insert $extId in the database
@Geo OK、私はあなたの解決策を試してみましたが、それは(もちろん)うまくいきましたが、その後、新しい問題が発生しました - あなたの「if」の「else」の部分で、
$extId = strtoupper(str_replace($problem_characters,rand(2,9),substr($code, 0, 7)));
while(true){
if((!in_array($extId, $allExternalIdsHandled)) && (!in_array($extId, $newEnteredValues))){
break;
}else{
$extId = strtoupper(str_replace($problem_characters,rand(2,9),substr($code, 0, 7))); }
}
//insert the modified value in the DB here
そのため、今は無限ループに入り、「random」呼び出しの実行で変更してから if に入って抜け出す必要がありますが、「break」コマンドで抜け出していません...
ここに問題はありません。誰かが私に指示を与えることができますか?
編集:ハングすることもあれば、ハングしないこともあります。10000 個の値を入力したところ、「else」パスを介して 2 つのエントリが変更されました。ログを使用してこれを観察しました。