2009-07-10 10 views
0

So ist das Hauptprogramm in C#. Einfügen neuer Datensätze in eine VFP-Datenbanktabelle Es wurde zu lange dauert die nächste ID für den Datensatz überVFP einfügen, Index Aktualisierung

select max(id)+1 from table 

zu erzeugen, so habe ich diesen Code in eine Kompilierung dll in VFP und bin, dass COM-Objekt über C# aufrufen.

Das COM-Objekt gibt die neue ID in etwa 250 ms zurück. Ich mache dann nur ein Update über OLEDB. Das Problem, das ich habe, ist, dass nach dem COM-Objekt der neu eingefügte ID zurückgibt, kann ich es sofort

über die OLEDB von C# nicht finden
select id form table where id = *newlyReturnedID* 

kehrt 0 Zeilen zurück. Wenn ich auf einen unbekannten Zeitraum warte, gibt die Abfrage eine Zeile zurück. Ich kann nur annehmen, dass es sofort 0 Zeilen zurückgibt, weil es noch die neu geprägte ID in den Index hinzufügen muss und daher die Auswahl nicht finden kann.

Hat jemand sonst jemals etwas Ähnliches gefunden? Wenn ja, wie sind Sie damit umgegangen?

DD

Antwort

4

Warnung: Ihr Code ist in einer Mehrbenutzerumgebung fehlerhaft. Zwei Personen können die Abfrage zur gleichen Zeit ausführen und die gleiche ID erhalten. Einer von ihnen wird auf dem INSERT fehlschlagen, wenn die Spalte einen Primär- oder einen Kandidatenschlüssel hat, was eine Best Practice für Schlüsselfelder ist.

Meine Empfehlung ist, entweder die ID ein automatisch inkrementieren Integer-Feld (ich bin kein Fan von ihnen), oder noch besser, erstellen Sie eine Tabelle von Schlüsseln. Jeder Datensatz in der Tabelle bezieht sich auf eine Tabelle, die Schlüssel zugewiesen bekommt. Ich benutze die eine ähnliche Struktur wie diese an:

 
     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 

Jetzt ist der Code für die gespeicherte Prozedur in der DBC (oder in einem anderen Programm) ist dies:

FUNCTION NextCounter (tcAlias)

LOCAL lcAlias,; lnNextValue,; lnOldReprozess,; lnOldArea

lnOldArea = SELECT()

IF PARAMETERS() lcAlias ​​= ALIAS()

IF CURSORGETPROP ("SOURCE") = DB_SRCLOCALVIEW * - Versuch Basistabelle zu erhalten lcAlias ​​= LOWER (CURSORGETPROP ("TABLES")) lcAlias ​​= SUBSTR (lcAlias, AT ("!", lcAlias) + 1) ENDIF ELSE lcAlias ​​= LOWER (tcAlias) ENDIF

lnOrderNumber = 0 lnOldReprocess = SET ('REPROCESS')

* - sperren, bis der Benutzer drückt Esc SET REPROCESS auf AUTOMATIC

IF USED ("countergenerator") USE Eventmanagement!countergenerator IN 0 SHARED ALIAS countergenerator ENDIF

SELECT countergenerator

IF Seek (LOWER (lcAlias), "countergenerator", "ckey") IF RLOCK() = lnNextValue countergenerator.iValue countergenerator.iValue REPLACE WITH countergenerator.iValue + 1 UNLOCK ENDIF ELSE * Erstellen Sie den neuen Datensatz mit dem Startwert. APPEND BLANK IN Gegengenerator SCATTER MEMVAR MEMO m.cKey = UNTERE (lcAlias) m.iValue = 1 m.mNote = "Automatisch von gespeicherten Prozedur erstellt." m.tUpdated = DATETIME-() GATHER MEMVAR MEMO

IF RLOCK() = lnNextValue countergenerator.iValue REPLACE countergenerator.iValue MIT countergenerator.iValue + 1 UNLOCK ENDIF ENDIF

SELECT (lnOldArea) SET REPROCESS TO

RETURN lnNextValue ENDFUNC

lnOldReprocess

Das RLOCK() stellt sicher, dass es keine Konflikte für die Datensätze gibt, und es ist schnell genug, um keinen Engpass im Prozess zu haben. Dies ist viel sicherer als die aktuelle Vorgehensweise.

Rick Schummer
VFP MVP

0

VFP braucht seine Workareas FLUSH.