AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Schnellste Insert Möglichkeit für eine DB?

Schnellste Insert Möglichkeit für eine DB?

Ein Thema von moelski · begonnen am 2. Mär 2010 · letzter Beitrag vom 9. Mär 2010
Antwort Antwort
Seite 5 von 5   « Erste     345
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#41

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 8. Mär 2010, 14:21
Zitat von xZise:
Nun ist das aktuell so, dass jeder ein Flag bekommt, ob er in der Liste ist und standard ist das keiner. Dann geht er jede Person auf der Liste durch und vergleicht das mit der Datenbankliste und setzt das Flag auf „vorhanden“. Wenn das nicht der Fall ist, wird die Person hinzufügt. Kann ich jetzt zu Anfang ein SQL Befehl erstellen (präventiv) und das dann nutzen, auch wenn zwischenzeitlich mal ein Update kommt?
Ich benutze SQLite, und hoffe mal, dass ich nicht geschlagen werde, dass ich keinen neuen Thread auf mache :)

MfG
Fabian
hat die "Schülerliste" in der DB kein Ausgeschieden Datum/Flag was auch immer?

Um wieviele Datensätze geht es?
Ich würde es so machen, (in der DB) alle Schüler auf ausgeschieden setzen, Schüler aus Liste in DB suchen, Falls vorhanden Ausgeschieden zurück setzen, falls nicht vorhanden eintragen.
(ähnlich mach ich es mit den Personen die ich verwalten darf (ca 3.000 Laufzeit ca 1Min) extra Server/oracle)

Diese Listen "Wer nicht vorhanden ist den gibt's nicht mehr" sind natürlich sehr fehleranfällig, es wäre besser wenn es zu jedem Namen so etwas wie eine Arbeitsanweisung gäbe (neu anlegen / löschen / auf vorhanden sein prüfen)

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#42

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 8. Mär 2010, 15:02
Moin,
genauso machen wir das ja auch im Moment. Und natürlich ist das Fehleranfällig, wenn man aber nur die Listen bekommt, wer alles ander Schule ist, dann kann man da nicht sehr viel anderes machen. Einzig, man könnte alle Schüler zum Schluss anzeigen, die gelöscht werden sollen.

Aber naja es ist eben nicht nur eine Personenliste, weshalb aktuell Personen ohne Klasse nicht existieren können.

Aber meine Frage ist halt, ob man quasi ganz am Anfang ein Query erstellen kann, auch wenn zwischenzeitlich andere Anweisungen durchgeführt werden. Wobei man könnte sogar mehrere Queries benutzen. Einmal ein „Schülerhinzufügen“-Query und ein „Schülervorhanden“-Query.

MfG
Fabian

PS: Es geht ingesamt nur um 1000 Schüler(innen).
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#43

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 8. Mär 2010, 15:31
Zitat von xZise:
Aber naja es ist eben nicht nur eine Personenliste, weshalb aktuell Personen ohne Klasse nicht existieren können.
Das geht nicht????

Zitat von xZise:
Aber meine Frage ist halt, ob man quasi ganz am Anfang ein Query erstellen kann, auch wenn zwischenzeitlich andere Anweisungen durchgeführt werden. Wobei man könnte sogar mehrere Queries benutzen. Einmal ein „Schülerhinzufügen“-Query und ein „Schülervorhanden“-Query.
Na klar kann man das, aber weil man das jederzeit kann, hab ich Deine Frage wohl nicht richtig verstanden.
Streng genommen gibt es keine "Schülerhinzufügen"-Abfrage nur eine Einfügen-Anweisung. Könntest Du vllt etwas Pseudo-Code produzieren?

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#44

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 8. Mär 2010, 15: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
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#45

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 9. Mär 2010, 10:34
Hallo xzise,

zunächst einmal, diese Auftrennung in Nachname und Vorname, und die nachfolgende Kombination zumindestens bei den Schülern erscheint mir doch sehr obskur. Oder habe ich die Funktion als Index übersehen?

wenn ich Deine Sourcen auf die SQL-Relevanz verkürze bleibt nur noch das übrig:
Code:

    // Alle Kurse und Kurszuweisungen löschen, die nicht Hauptkurse sind
    EntferneZuSQL('Kurse', 'Hauptkurs <> 0');
   
    EntferneZuSQL('Kurszuweisungen', 'KursID IN (SELECT KursID FROM Kurse WHERE Hauptkurs <> 0)');
   
    // Und dann die Schüler auf obsolet setzen
    ExecSQL('UPDATE Personen SET Obsolet = -1 WHERE HauptKursID != 0');
   

    BeginTransaction;
Zunächst steht da ziemlich verloren ein einsames BeginTransaction, nur noch gefolgt von Datenmanipulationen aber ohne irgendeinen Datenbankbezug (was hab ich da übersehen?).

Und was macht EntferneZuSql ? Wenn ich das richtig verstanden habe, wird jedes mal auf der Datenbank eine wílde Datensammlung erzeugt, die dann wieder bereinigt wird? (Hauptkurs oder nicht)
Dieser "Datenmissbrauch" ist die Grundlage von Chaos-Programmen. Wenn man das Geschlecht einer Person bestimmen/dokumentieren will, dann braucht's ein Feld Geschlecht und keine Umwege über Vorname, Schuhgröße, Haarlänge und was für kreative Ideen da noch herum schwirren. (Übrigens, das der Titel bei Lehrer die ersten fünf Stellen des Namens belegt ist auch so eine Krücke die Fehler geradezu provoziert)

Da sollte das Konzept, das dahinter steht einmal überdacht werden.

Wenn es Dir darum geht, Dein Programm zu beschleunigen, dann solltest Du von diesem
Code:
 GeneriereDoppelFortschritt(i_cAnzahlSchritte...
Abstand nehmen, denn das ist ein echter Zeitfresser.

Zitat:
Aber die Frage die sich mir stellt, ist halt ob ich zwei Queries parallel laufen haben kann.
Das ginge, aber was soll es bringen? Die query die als erste startet, hat den Datenbestand mehr oder weniger exclusiv im Zugriff (kommt auf die dahinter liegende "Sperrungsphilosophie" an) die zweite muß dementsprechend warten. Wenn Du Zeit sparen willst, solltest Du Dir dein Programm einmal sehr kritisch anschauen, und vor allem die Frage stellen wofür das, was da gemacht wird, eigentlich gut ist.

gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#46

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 9. Mär 2010, 10:56
Moin,
ich weiß, es ist nicht gerade ideal gelöscht, aber wir bekommen halt eine Liste mit Namen von Schülern. Das heißt wir können nicht (was wesentlich besser ist) testen, ob eine PersonenID noch existiert, sondern stattdessen uns darauf verlassen, dass es keine zwei Personen mit den gleichen Vornamen und Nachnamen parallel gibt.

Und ich verstehe deine „SQL-Relevanz“ nicht. Das alles vor den BeginTransaction bereitet die Datenbank vor. Es ist halt nicht eben nur eine einfache Personenliste, sondern wir speichern zusätzlich auch die Kurse/Klassen der einzelnen Schüler. Dazu gibt es die Tabelle Kurse und Kurszuweisungen. Der erste Befehl, löscht nun alle Kurse, die ein Hauptkurs sind während der zweite Befehl dann alle Zuweisungen löschen soll. Das heißt er löscht die Information, welche Schüler in den Kursen waren, die gelöscht wurden. Okay ich glaube das muss andersherum ausgeführt werden.
Der dritte Befehl, setzt dann präventiv alle Schüler erst mal auf überflüssig (der Hauptkurs ist eben nicht 0, das sind die Lehrer) also Obsolet ist nicht 0.

So und dann kommen wir in den interessanten Bereich:
Nun gehen wir jede Klasse der Exceltabelle durch. Oben rechts steht dann immer "Herr/Frau ...", nagut das es immer 5 sind, ist nicht direkt gegeben, das schaue ich mir mal an, wie man das anders macht (wohl eher dann mit Pos etc.).

Also ermittelt er erstmal den Lehrer/die Lehrerin, wenn sie nicht existiert, MUSS sie erstellt werden, weil daraufhin dann wieder ein neuer Kurs angelegt wird und dieser MUSS umbedingt eine Valide LehrerID haben!

Dann geht er jeden Schüler dieses Kurses durch und liest den Namen ein und prüft, ob er bereits existiert. Wenn er nicht existiert (bzw. der Vorname und Nachname), dann ruft er iFügeSchülerHinzu auf, welche einen Schüler hinzufügt. Alternativ setzt er den Schüler auf nicht überflüssig (Obsolet = 0). Zusätzlich setzt er dann auch die neue HauptkursID.

Okay ich habe mich zu lange nicht damit beschäftigt, weshalb da nicht nur zwei SQL Statements vorkommen:
Um eine Person hinzufügen (das ist der Inhalt von iFuegeSchuelerHinzu):
INSERT INTO Personen(Name,Vorname,HauptKursID,Obsolet) VALUES ("AName", "AVorname" , 0, 0) So und für jede Person gilt das (das ist der Inhalt von WeiseHauptKursIDZuPIDZu, welche von iFuegeSchuelerHinzu aufgerufen wird!):
SQL-Code:
DELETE FROM Kurszuweisungen WHERE PersonenID = ASchuelerID AND KursID = AKursID
UPDATE Personen SET HauptKursID = AKursID WHERE PersonenID = APersonenID
INSERT INTO Kurszuweisungen (PersonenID, KursID) VALUES (ASchuelerID, AKursID)
Okay, das DELETE Statement ist überflüssig, weil wir zu Anfang da ja aufgeräumt haben.
Und Alle Werte mit A.... sind Variablen und beim hinzufügen der Person, bekomme ich die SchülerID zurückgegeben.

Und ganz zum Schluss, lösche ich dann alle Schüler, die obsolet markiert wurden.

Sofern das nicht weiter zu optimieren ist, lasse ich dennoch das GeneriereDoppelFortschritt( drin, damit der Anwender eine Rückmeldung bekommt.

MfG
Fabian
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat
Benutzerbild von Sharky
Sharky

Registriert seit: 29. Mai 2002
Ort: Frankfurt
8.251 Beiträge
 
Delphi 2006 Professional
 
#47

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 9. Mär 2010, 12:07
Hai ihr,

hat das mti der "Schülerliste" noch etwas mit dem Ursprungsthema zu tun?
Stephan B.
"Lasst den Gänsen ihre Füßchen"
  Mit Zitat antworten Zitat
Benutzerbild von p80286
p80286

Registriert seit: 28. Apr 2008
Ort: Stolberg (Rhl)
6.659 Beiträge
 
FreePascal / Lazarus
 
#48

Re: Schnellste Insert Möglichkeit für eine DB?

  Alt 9. Mär 2010, 13:46
@Sharky
Ich denke jetzt wieder

@xZise
jetzt hast Du die Chance über die Parameter Geschwindigkeit zu machen z.b. so:
Delphi-Quellcode:
  q.sqltext:='INSERT INTO Personen(Name,Vorname,HauptKursID,Obsolet) VALUES (:AName, :AVorname , 0, 0);
for i:=0 to liste.count-1 do begin
q.parambyname(
'Aname').asstring:=liste[i].Name;
q.parambyname(
'Avorname').asstring:=liste[i].Vorname;
q.sqlexec;
end;
So sollte es im Prinzip ablaufen. Der Einfacheit halber ist bei mir Liste keine Stringliste, aber ich denke das Prinzip ist klar.

SQL-Code:
DELETE FROM Kurszuweisungen WHERE PersonenID = ASchuelerID AND KursID = AKursID
UPDATE Personen SET HauptKursID = AKursID WHERE PersonenID = APersonenID
INSERT INTO Kurszuweisungen (PersonenID, KursID) VALUES (ASchuelerID, AKursID)
auch hier solltest Du (wenn möglich!) erst alle DELETE-Anweisungen, dann die UPDATEs und dann die INSERTs ausführen lassen.
Natürlich unter Ausnutzung der Parameter.
was die Transaktion angeht, würde ich jede for i:=.Schleife in eine Transaktion packen, aber das ist eine reine Bauchempfehlung.

Gruß
K-H
Programme gehorchen nicht Deinen Absichten sondern Deinen Anweisungen
R.E.D retired error detector
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz