警告: あなたのコードはマルチユーザー環境で欠陥があります. 2 人のユーザーが同時にクエリを実行し、同じ ID を取得する可能性があります。列に主キーまたは候補キーがある場合、そのうちの 1 つが INSERT で失敗します。これは、キー フィールドのベスト プラクティスです。
ID を自動インクリメントの整数フィールドにするか (私はそれらのファンではありません)、キーのテーブルを作成することをお勧めします。テーブル内の各レコードは、割り当てられたキーを取得するテーブル用です。私はこれに似た構造を使用します:
構造: countergenerator.dbf
データベース名: conferencereg.dbc
長いテーブル名: countergenerator
レコード数: 0
最終更新日: 2008 年 11 月 8 日
メモファイルのブロックサイズ:64
コードページ: 1252
テーブル タイプ: Visual FoxPro テーブル
フィールド名 タイプ サイズ Null 次のステップ デフォルト
-------------------------------------------------- -------------------------------------------------- ------------
1 ccountergenerator_pk 文字 36 N guid(36)
2 ckey 文字 (バイナリ) 50 Y
3 ivalue 整数 4 Y
4mメモメモ4Y「自動作成」
5 cuserid キャラクター 30 Y
6 tupdated DateTime 8 Y DATETIME()
索引タグ:
1.タグ名:PRIMARY
- タイプ: プライマリ
- キー式: ccountergenerator_pk
- フィルター: (なし)
- 順序: 昇順
- 丁合順:機械
2.タグ名:CKEY
- タイプ: レギュラー
- キー表現: 下(ckey)
- フィルター: (なし)
- 順序: 昇順
- 丁合順:機械
DBC (または別のプログラム) のストアド プロシージャのコードは次のとおりです。
FUNCTION NextCounter(tcAlias)
LOCAL lcAlias、; lnNextValue、; lnOldReprocess, ; 旧エリア
lnOldArea = SELECT()
IF PARAMETERS() < 1 lcAlias = エイリアス()
IF CURSORGETPROP("SOURCETYPE") = DB_SRCLOCALVIEW *-- ベース テーブルを取得しようとしています lcAlias = LOWER(CURSORGETPROP("TABLES")) lcAlias = SUBSTR(lcAlias, AT("!", lcAlias) + 1) ENDIF ELSE lcAlias = LOWER (tcAlias) ENDIF
lnOrderNumber = 0 lnOldReprocess = SET('再処理')
*-- ユーザーが Esc を押すまでロックする SET REPROCESS TO AUTOMATIC
IF !USED("countergenerator") USE EventManagement!countergenerator IN 0 SHARED ALIAS countergenerator ENDIF
カウンタージェネレーターを選択
IF SEEK(LOWER(lcAlias), "countergenerator", "ckey") IF RLOCK() lnNextValue = countergenerator.iValue REPLACE countergenerator.iValue WITH countergenerator.iValue + 1 UNLOCK ENDIF ELSE * 開始値で新しいレコードを作成します。APPEND BLANK IN countergenerator SCATTER MEMVAR MEMO m.cKey = LOWER(lcAlias) m.iValue = 1 m.mNote = "ストアド プロシージャによって自動的に作成されます。" m.tUpdated = DATETIME() GATHER MEMVAR MEMO
IF RLOCK() lnNextValue = countergenerator.iValue countergenerator.iValue WITH countergenerator.iValue + 1 UNLOCK ENDIF ENDIF を置換
SELECT (lnOldArea) 再処理を lnOldReprocess に設定
RETURN lnNextValue ENDFUNC
RLOCK() は、レコードの競合がないことを保証し、プロセスのボトルネックにならないほど高速です。これは、現在取っているアプローチよりもはるかに安全です。
リック・シューマー
VFP MVP