VFP-Einfügung, Indexaktualisierung
-
12-09-2019 - |
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
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 .