2009-07-10 23 views
0

したがって、メインプログラムはC#にあります。新しいレコードをVFPデータベーステーブルに挿入する。それはVFP挿入、インデックス更新

select max(id)+1 from table 

経由でレコードの次のIDを生成するために時間がかかりすぎたので、私はVFPでコンパイルDLLにそのコードを入れて、C#のを通じてそのCOMオブジェクトを呼び出しています。

COMオブジェクトは約250msで新しいIDを返します。私はOLEDBを使って更新します。私が午前問題は、COMオブジェクトが新たに挿入されたIDを返した後、私はすぐに戻って

select id form table where id = *newlyReturnedID* 

戻り0行をOLEDB経由でのC#からそれを見つけることができないということです。私が不明な時間を待つと、クエリは1行を返します。インデックスに新しく作成されたIDをまだ追加していないので、すぐに0行が返されると仮定することができます。したがって、選択できません。

他に誰かが似たようなことをしたことはありますか?もしそうなら、どうやってそれを扱ったのですか?

DD

答えて

4

警告:コードには、マルチユーザー環境での欠陥があります。 2人で同時にクエリを実行し、同じIDを取得できます。カラムにプライマリまたは候補キーがある場合、そのうちの1つはINSERTで失敗します。これはキーフィールドのベストプラクティスです。

私は、IDを自動インクリメント整数フィールド(私はそれらのファンではない)にするか、またはそれ以上にキーのテーブルを作成することをお勧めします。テーブルの各レコードは、キーが割り当てられたテーブル用です。私はこれに類似した構造を使用:

FUNCTION NextCounter(tcAlias)

LOCAL:今DBC(または別のプログラムで)でストアドプロシージャのコードを

 
     Structure for: countergenerator.dbf 
     Database Name: conferencereg.dbc 
    Long table name: countergenerator 
    Number of records: 0 
     Last updated: 11/08/2008 
Memo file block size: 64 
      Code Page: 1252 
      Table Type: Visual FoxPro Table 

Field Name     Type     Size Nulls  Next  Step Default 
---------------------------------------------------------------------------------------------------------------- 
    1 ccountergenerator_pk Character   36   N      guid(36) 
    2 ckey     Character (Binary) 50   Y       
    3 ivalue    Integer    4   Y       
    4 mnote     Memo     4   Y      "Automatically created" 
    5 cuserid    Character   30   Y       
    6 tupdated    DateTime    8   Y      DATETIME() 

Index Tags: 
1. Tag Name: PRIMARY 
- Type: primary 
- Key Expression: ccountergenerator_pk 
- Filter: (nothing) 
- Order: ascending 
- Collate Sequence: machine 

2. Tag Name: CKEY 
- Type: regular 
- Key Expression: lower(ckey) 
- Filter: (nothing) 
- Order: ascending 
- Collate Sequence: machine 

このありますlcAlias、;lnNextValue、; lnOldReprocess、; lnOldArea

lnOldArea = SELECT()

パラメータ() lcAlias IF = ALIAS()

CURSORGETPROP IF( "SOURCETYPE")= DB_SRCLOCALVIEW * - ベーステーブル を取得しようlcAlias = LOWER(CURSORGETPROP( "TABLES")) lcAliasの=のSUBSTR(lcAlias、AT( "!"、lcAlias)+ 1) ENDIF ELSE lcAlias = LOWER(tcAlias) ENDIF

lnOrderNumber = 0 lnOldReprocess = SET( 'REPROCESS')

* - ロックすると、ユーザーは自動

Escキー のSET REPROCESSを押すまで( "countergenerator") 使用EventManagementを使用しました!0 SHARED ALIASのcountergenerator IN countergenerator ENDIF

SELECT countergenerator

()lcAlias(LOWER、 "countergenerator"、 "CKEY")を求めるなら RLOCK() lnNextValue = countergenerator.iValue countergenerator.iValueを交換する場合WITH countergenerator.iValue + 1 UNLOCK ENDIF ELSE *開始値で新しいレコードを作成します。 countergenerator 散乱MEMVARのMEMO IN APPENDのBLANK m.cKey = LOWER(lcAlias) m.iValue = 1 m.mNote = "自動的にストアドプロシージャによって作成されました"。 m.tUpdated = DATETIME() RLOCK()は lnNextValue = countergenerator.iValue ENDIF ENDIF

countergenerator.iValue WITH countergenerator.iValue + 1 UNLOCKを交換した場合SELECT(lnOldArea MEMVARのMEMO

を収集

RETURN lnNextValue ENDFUNC

をlnOldReprocess TO) のSET REPROCESS

RLOCK()は、レコードの競合がないことを保証し、プロセスのボトルネックを起こさないほど速いです。これはあなたが現在取っているアプローチよりも安全です。

リック・シューマー
VFP MVP

0

VFPは、そのワークエリアをFLUSHする必要があります。