Frage

Das Hauptprogramm ist also in C#.Einfügen neuer Datensätze in eine VFP-Datenbanktabelle.Es hat zu lange gedauert, die nächste ID für den Datensatz zu generieren

select max(id)+1 from table

, also habe ich diesen Code in eine Kompilierungs-DLL in VFP eingefügt und rufe dieses COM-Objekt über C# auf.

Das COM-Objekt gibt die neue ID in etwa 250 ms zurück.Ich mache dann einfach ein Update über OLEDB.Das Problem, das ich habe, ist, dass ich, nachdem das COM-Objekt die neu eingefügte ID zurückgegeben hat, sie nicht sofort in C# über die OLEDB finden kann

select id form  table where id = *newlyReturnedID*

gibt 0 Zeilen zurück.Wenn ich eine unbekannte Zeitspanne warte, gibt die Abfrage 1 Zeile zurück.Ich kann nur davon ausgehen, dass sofort 0 Zeilen zurückgegeben werden, da die neu erstellte ID noch nicht zum Index hinzugefügt wurde und die Auswahl sie daher nicht finden kann.

Ist irgendjemand schon einmal auf etwas Ähnliches gestoßen?Wenn ja, wie sind Sie damit umgegangen?

DD

War es hilfreich?

Lösung

Warnung:Ihr Code ist in einer Mehrbenutzerumgebung fehlerhaft.Zwei Personen könnten die Abfrage gleichzeitig ausführen und dieselbe ID erhalten.Einer von ihnen schlägt beim INSERT fehl, wenn die Spalte einen Primär- oder Kandidatenschlüssel hat, was eine bewährte Methode für Schlüsselfelder ist.

Meine Empfehlung ist, dass die ID entweder ein automatisch inkrementierendes Ganzzahlfeld ist (ich bin kein Fan davon) oder, noch besser, eine Schlüsseltabelle zu erstellen.Jeder Datensatz in der Tabelle bezieht sich auf eine Tabelle, der Schlüssel zugewiesen werden.Ich verwende eine Struktur ähnlich dieser:

       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

Der Code für die gespeicherte Prozedur im DBC (oder in einem anderen Programm) lautet nun wie folgt:

FUNKTION NextCounter(tcAlias)

LOCAL lcAlias, ;lnNextValue, ;lnOldReprocess, ;lnOldArea

lnOldArea = SELECT()

Wenn Parameter () <1 lcalias = alias ()

Wenn cursorgetProp ("Sourcetyp") = db_srclocalview *- Versuchen Sie, Basistabelle Lcalias = Lower (CursorgetProp ("Tabellen") Lcalias = substr (lcalias, at ("! (tcalias) endif

lnorderNumber = 0 lnoldreProcess = set ('Wiederaufbereitung')

*- Sperren Sie, bis der Benutzer ESC-Setzen Sie die Wiederaufbereitung auf automatisch ein.

If! Us ("Countergenerator") Verwenden Sie EventManagement! Gegengenerator in 0 Shared Alias ​​Gegengenerator Endif

Gegengenerator AUSWÄHLEN

Wenn such (niedriger (lcalias), "Countergenerator", "CKY"), wenn rlock () lnnextValue = Gegengenerator.Versvaller ersetzen.Blank im Gegengenerator -Streuememvar -Memo anhängen m.ckey = niedriger (lcalias) m.alivalue = 1 m.mnote = "Automatisch durch gespeicherte Prozedur erstellt". M.Tupdated = DateTime () Memvar Memo sammeln

If rlock () lnnextValue = countergenerator

Select (lnoldarea) Setzen

Return lnnextValue endfunc

RLOCK() stellt sicher, dass es keine Konkurrenz um die Datensätze gibt und ist schnell genug, um keinen Engpass im Prozess zu verursachen.Das ist viel sicherer als der Ansatz, den Sie derzeit verfolgen.

Rick Schummer
VFP MVP

Andere Tipps

VFP muss FLUSH .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top