Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
Delphi 2009 Professional
|
Re: Schnellste Insert Möglichkeit für eine DB?
8. Mär 2010, 16:58
Moin,
naja es ist schon etwas her (6 Monate) und habe nicht mehr die genauen Spezifikationen vor Augen, aber das Problem ist, dass jede Person einen sogenannten Hauptkurs hat. Dieser Hauptkurs ist entweder ungültig und definiert damit einen Lehrer oder eben ein Schüler, dafür muss es aber ein Hauptkurs geben.
Ich habe demnächst wieder eine 6 Stunden Zugfahrt vor mir, wo ich mir evtl. das mal anschaue!
Aber die Frage die sich mir stellt, ist halt ob ich zwei Queries parallel laufen haben kann.
Und Pseudocode, öhrm, ich hoffe der Code ist soweit selbst erklärend:
Delphi-Quellcode:
procedure TDatenbankStationBasis.SchuelerEinlesen(const sDateiname: string);
const
ANZAHL_ERSTER_SCHRITTE = 11;
var
oExcel : TExcelApplication;
oWorkbook : _WorkBook;
oWorksheet : _WorkSheet;
cLCID : Cardinal;
i, j, iLehrerID, iJahrgang, iSchuelerAnzahl, iPersonenID : Integer;
sKlasse, sKlassenlehrer, sName, sVorname : string;
ILLehrerIDs, ILKursIDs, ILSchuelerIDs : TIntegerList;
SLLehrerNachnamen, SLKursNamen, SLSchuelerNamen, SLSchuelerVornamen, SLSchuelerNachnamen : TStrings;
ILPersonenIDs: TIntegerList;
ILExemplarIDs: TIntegerList;
i_cAnzahlSchritte: Integer;
iAktuellerSchritt, iUeberAllesSchritt : Integer;
iKursID: Integer;
begin
oExcel := TExcelApplication.Create(nil);
ILLehrerIDs := TIntegerList.Create;
ILKursIDs := TIntegerList.Create;
ILSchuelerIDs := TIntegerList.Create;
ILPersonenIDs := TIntegerList.Create;
ILExemplarIDs := TIntegerList.Create;
SLLehrerNachnamen := TStringList.Create;
SLSchuelerNamen := TStringList.Create;
SLSchuelerVornamen := TStringList.Create;
SLSchuelerNachnamen := TStringList.Create;
SLKursNamen := TStringList.Create;
try
cLCID := GetUserDefaultLCID;
oExcel.Connect;
// Exceldatei laden
try
oWorkbook := oExcel.Workbooks.Open(sDateiname, emptyParam, true, emptyParam, emptyParam,
emptyParam, emptyParam, emptyParam, emptyParam, emptyParam, emptyParam,
emptyParam, emptyParam, emptyParam, emptyParam, cLCID);
except
on E : EOleSysError do
begin
raise EExcelNichtGefunden.CreateDef(e.Message);
end;
end;
i_cAnzahlSchritte := oExcel.Worksheets.Count + 2;
iAktuellerSchritt := 0;
iUeberAllesSchritt := 0;
// Alle LehrerIDs auslesen ...
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Einlesen starten', hstVorbereitung);
GibLehrerIDs(ILLehrerIDs);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'LehrerIDs puffern', hstVorbereitung);
// ... und dessen Nachnamen speichern
GibNamenZuPIDL(SLLehrerNachnamen, ILLehrerIDs);
ILLehrerIDs.IntegrateInStrings(SLLehrerNachnamen);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Lehrer Nachnamen puffern', hstVorbereitung);
// Dann die KursIDs einlesen ...
GibKursIDs(ILKursIDs);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Kurse puffern', hstVorbereitung);
// ... und dessen Namen speichern
GibKursnamenZuKIDL(SLKursNamen, ILKursIDs);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Kursnamen puffern', hstVorbereitung);
// Alle SchülerIDs einlesen ...
GibSchuelerIDs(ILSchuelerIDs);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Schüler puffern', hstVorbereitung);
// ... und dessen Nachnamen speichern ...
GibNamenZuPIDL(SLSchuelerNachnamen, ILSchuelerIDs);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Schüler Nachnamen puffern', hstVorbereitung);
// ... sowie dessen Vornamen ...
GibVornamenZuPIDL(SLSchuelerVornamen, ILSchuelerIDs);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Schüler Vornamen puffern', hstVorbereitung);
// ... und diese dann kombinieren
for j := 0 to SLSchuelerNachnamen.Count - 1 do
SLSchuelerNamen.Add(SLSchuelerNachnamen[j] + '&' + SLSchuelerVornamen[j]);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Schüler Namen puffern', hstVorbereitung);
// Alle Kurse und Kurszuweisungen löschen, die nicht Hauptkurse sind
EntferneZuSQL('Kurse', 'Hauptkurs <> 0');
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Kurse löschen', hstVorbereitung);
EntferneZuSQL('Kurszuweisungen', 'KursID IN (SELECT KursID FROM Kurse WHERE Hauptkurs <> 0)');
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Kurszuweisungen löschen', hstVorbereitung);
// Und dann die Schüler auf obsolet setzen
ExecSQL('UPDATE Personen SET Obsolet = -1 WHERE HauptKursID != 0');
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ANZAHL_ERSTER_SCHRITTE, iUeberAllesSchritt, iAktuellerSchritt, 'Personen zum Löschen markieren', hstVorbereitung);
BeginTransaction;
for i := 1 to oExcel.Worksheets.Count do
begin
oWorksheet := oWorkbook.Sheets[i] as _WorkSheet;
sKlasse := oWorksheet.Name;
j := 1;
while (CharInSet(sKlasse[j], ['0'..'9'])) and (j <= Length(sKlasse)) do
Inc(j);
iJahrgang := StrToIntDef(Copy(sKlasse, 1, j - 1), -1);
// Lehrer einlesen (wenn der Name zu lang ist, ist der in der nächsten
// Zeile)
sKlassenlehrer := oWorksheet.Cells.Item[2, 5].Value + oWorksheet.Cells.Item[3, 5].Value;
// Anrede entfernen
Delete(sKlassenlehrer, 1, 5);
GeneriereDoppelFortschritt(i_cAnzahlSchritte, 1, iUeberAllesSchritt, iAktuellerSchritt, 'Tabelle/Klasse "' + sKlasse + '" wird eingelesen', hstEinlesen);
if (iJahrgang >= 0) and (Length(sKlassenlehrer) > 0) then
begin
// Position des Nachnamens feststellen
iLehrerID := SLLehrerNachnamen.IndexOf(sKlassenlehrer);
// Lehrer existiert nicht
if iLehrerID = -1 then
begin
// Dann nachfragen was geschehen soll
if Assigned(fELF) then
fELF(self, sKlassenlehrer, sKlasse, iLehrerID);
if (iLehrerID = -1) or (not boIstLehrerZuPID(iLehrerID)) then
raise ELehrerNichtGefunden.Create('Kein Lehrer zur Kurszuweisung gefunden.');
end
else //Lehrer vorhanden
begin
iLehrerID := Integer(SLLehrerNachnamen.Objects[iLehrerID]);
ExecSQL('UPDATE Personen SET Obsolet = 0 WHERE PersonenID = '+ IntToStr(iLehrerID));
end;
// Gültige ID
if iLehrerID > 0 then
begin
// Neuen Kurs anlegen
iKursID := iFuegeKursHinzu(iJahrgang, iLehrerID, sKlasse, True);
j := 10;
while oWorksheet.Cells.Item[j, 2].Value <> '' do
begin
Inc(j);
end;
iSchuelerAnzahl := j - 10;
if iSchuelerAnzahl = 0 then
GeneriereDoppelFortschritt(i_cAnzahlSchritte, 1, iUeberAllesSchritt, iAktuellerSchritt, 'Klasse ' + sKlasse + ' eingelesen', hstEinlesen);
for j := 0 to iSchuelerAnzahl - 1 do
begin
sName := oWorksheet.Cells.Item[j + 10, 2].Value;
sVorname := sName;
Delete(sName, Pos(',', sName), Length(sName) - Pos(',', sName)+1);
Delete(sVorname, 1, Pos(',', sVorname) + 1);
sName := Trim(sName);
sVorname := Trim(sVorname);
iPersonenID := ILSchuelerIDs.IntegersDef(SLSchuelerNamen.IndexOf(sName + '&' + sVorname), -1);
// Überprüfen ob die PersonenID gültig ist
if iPersonenID = -1 then
begin
iFuegeSchuelerHinzu(sName, sVorname, iKursID);
end else
begin
WeiseHauptKursIDZuPIDZu(iPersonenID, iKursID);
end;
// Fortschritssbalken updaten
GeneriereDoppelFortschritt(i_cAnzahlSchritte, iSchuelerAnzahl, iUeberAllesSchritt, iAktuellerSchritt, 'Klasse: ' + sKlasse + ' Schüler: ' + sName + ' eingelesen', hstEinlesen);
end;
end else
begin
GeneriereDoppelFortschritt(i_cAnzahlSchritte, 1, iUeberAllesSchritt, iAktuellerSchritt, 'Klasse: ' + sKlasse + ' übersprungen', hstEinlesen);
end;
end else
begin
GeneriereDoppelFortschritt(i_cAnzahlSchritte, 1, iUeberAllesSchritt, iAktuellerSchritt, 'Unbekannte Klasse übersprungen', hstEinlesen);
end;
end;
// Zu entfernen Einträge wieder entfernen.
ILSchuelerIDs.Clear;
ILLehrerIDs.Clear;
SLLehrerNachnamen.Clear;
SLKursNamen.Clear;
SLSchuelerNamen.Clear;
SLSchuelerVornamen.Clear;
SLSchuelerNachnamen.Clear;
// Gib alle IDs die nun obsolet sind
GeneriereDoppelFortschritt(i_cAnzahlSchritte, 1, iUeberAllesSchritt, iAktuellerSchritt, 'Überprüfe Datenbank', hstAufraeumen);
GibObsoleteIDs(ILPersonenIDs, true);
if ILPersonenIDs.Count = 0 then
GeneriereDoppelFortschritt(i_cAnzahlSchritte, 1, iUeberAllesSchritt, iAktuellerSchritt, 'Löschen abgeschlossen', hstAufraeumen);
for i := 0 to ILPersonenIDs.Count - 1 do
begin
if iGibAnzahlAusgeliehenZuPID(ILPersonenIDs[i]) = 0 then
begin
// Benutzer hat keine Bücher ausgeliehen und ist obsolet -> kann
// gelöscht werden, aber zuerst die Kurszuweisungen
ExecSQL('DELETE FROM Kurszuweisungen WHERE PersonenID = ' + IntToStr(ILPersonenIDs[i]));
ExecSQL('DELETE FROM Personen WHERE PersonenID = ' + IntToStr(ILPersonenIDs[i]));
end;
GeneriereDoppelFortschritt(i_cAnzahlSchritte, ILPersonenIDs.Count, iUeberAllesSchritt, iAktuellerSchritt, 'Lösche Personen', hstAufraeumen);
end;
Commit;
oWorkbook.Close(False, emptyParam, emptyParam, cLCID);
oExcel.Quit;
finally
oExcel.Free;
ILLehrerIDs.Free;
ILSchuelerIDs.Free;
ILPersonenIDs.Free;
ILKursIDs.Free;
ILExemplarIDs.Free;
SLKursNamen.Free;
SLLehrerNachnamen.Free;
SLSchuelerNamen.Free;
SLSchuelerNachnamen.Free;
SLSchuelerVornamen.Free;
end;
end;
Ich weiß, es gibt einige Stellen die man mit Parametern machen sollte, aber darum wollte ich mich eh erst in der nächsten Woche kümmern.
MfG
Fabian
Fabian Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
|