Domanda

Quindi il programma principale è in C#.Inserimento di nuovi record in una tabella di database VFP.La generazione dell'ID successivo per il record tramite ha richiesto troppo tempo

select max(id)+1 from table

, quindi inserisco il codice in una DLL di compilazione in VFP e chiamo l'oggetto COM tramite C#.

L'oggetto COM restituisce il nuovo ID in circa 250 ms.Quindi eseguo semplicemente un aggiornamento tramite OLEDB.Il problema che sto riscontrando è che dopo che l'oggetto COM restituisce l'ID appena inserito, non riesco a trovarlo immediatamente da C# tramite OLEDB

select id form  table where id = *newlyReturnedID*

restituisce 0 righe indietro.Se aspetto un periodo di tempo sconosciuto, la query restituirà 1 riga.Posso solo supporre che restituisca immediatamente 0 righe perché deve ancora aggiungere l'ID appena coniato nell'indice e quindi la selezione non riesce a trovarlo.

Qualcun altro si è mai imbattuto in qualcosa di simile?Se sì, come hai fatto a gestirlo?

GG

È stato utile?

Soluzione

Avvertimento:il tuo codice è difettoso in un ambiente multiutente.Due persone potrebbero eseguire la query contemporaneamente e ottenere lo stesso ID.Uno di questi fallirà sull'INSERT se la colonna ha una chiave primaria o candidata, che è una procedura consigliata per i campi chiave.

Il mio consiglio è di fare in modo che l'ID sia un campo intero con incremento automatico (non ne sono un fan) o, ancora meglio, di creare una tabella di chiavi.Ogni record nella tabella è per una tabella a cui vengono assegnate le chiavi.Utilizzo una struttura simile a questa:

       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

Ora il codice per la procedura memorizzata nel DBC (o in un altro programma) è questo:

FUNZIONE NextCounter(tcAlias)

Alias ​​lcLOCALE, ;lnValoresuccessivo, ;lnOldReprocess, ;lnOldArea

lnOldArea = SELEZIONA()

If parametri () <1 lcalias = alias ()

Se CURSORGetProp ("SourceType") = db_srclocalview *- tentativo di ottenere la tabella di base LCALIAS = inferiore (cursorgetProp ("tabelle")) lcALIA (TCALIAS) ENDIF

lNorderNumber = 0 lNoldreProcess = set ('Reprocess')

*- Blocca fino a quando l'utente preme ESC Imposta il ritrattamento su automatico

If! Usate ("controgenerator") usa eventmanagement! Controgeneratore in 0 alias condiviso controgenerator endif

SELEZIONA controgeneratore

Se cerca (inferiore (lcALIAS), "controgeneratore", "ckey") se rlock () lnnextValue = controgenerator.ivalue sostituisci controgenerator.ivalue con controgenerator.vale + 1 scolore else else * crea il nuovo record con il valore iniziale.Appendere il vuoto nel controgeneratore Scatter Memvar Memo M.Ckey = Lower (LCALIAS) M.Vivalue = 1 M.MNote = "Creato automaticamente dalla procedura memorizzata." m.tupdated = datetime () raccogli il memo memvar

Se rlock () lnNextValue = controgeneratore.Vivalue Sostituisci controgenerator.Vivalue con controgenerator.Vivalue + 1 Sblocca ENDIF ENDIF

Seleziona (LNoldarEa) Imposta il ritrattamento su lnorreprocess

Return lnnextValue endfunc

RLOCK() garantisce che non vi siano conflitti per i record ed è sufficientemente veloce da non creare colli di bottiglia nel processo.Questo è molto più sicuro dell’approccio che stai adottando attualmente.

Rick Schummer
MVP del VFP

Altri suggerimenti

FLUSH suoi un'aree .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top