Announcement

Collapse
No announcement yet.

Umstieg TQuery auf ADOQuery

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Umstieg TQuery auf ADOQuery

    Hi liebe Delphianer,

    Ich frage mich nur wie die anderen das lösen?

    Was passiert wenn ihr einen kunden (stammdatensatz!) aus der Tabelle löscht? Dann existiert möglicherweise noch ein "verwaister" Datensatz in der Rechnungstabelle, die mit ihrem Fremdschlüssel auf einen nun nicht mehr vorhandenen Kunden zeigt.

    Ich weiß das das bei Paradox mit der Referentiellen Integrität geht, aber bei Access2000 hab ich schwierigkeiten.

    HAb das ganze in Ordner Delphi Anfänger diskutiert und bräuchte Hilfe bei folgendem Code!

    <pre>procedure TForm1.KundenTableBeforeDelete(DataSet:TDataset);
    var aKey :String;
    DelQuery:TQuery;
    begin
    // Kunde der gelöscht wird
    aKey:=DataSet.FieldByName('e_key').AsString;
    // Löschabfrage generieren und die Datensätze löschen, bei denen
    // e_Key=aKey ist
    DelQuery:=TQuery.Create(Self);
    with DelQuery do
    try
    SQL.Add('DELETE FROM "..\detailtabelle"');
    SQL.Add('WHERE e_key=:loeschkey');
    Params[0].AsString:=aKey;
    ExecSQL;
    finally
    Free;
    end; // with DelQuery
    end; // TForm1.KundenTableBeforeDelete </pre>

    Ich habe ein problem bei <pre>Params[0].AsString:=aKey; </pre>
    den bei ADOQuery gibts das Params nicht, und ich kann irgendwie nicht auf die parameters zugreifen (weiß auch den Code nicht!)

    WER HILFT MIR?

    BINE :_)

  • #2
    Hallo,

    so kompliziert muss man das bei ADO gar nicht machen, da bereits TADOConnection mit der Methode <b>Execute</b> einen schnellen und einfacheren Weg bereitstellt:
    <pre>
    sSQL := Format('DELETE FROM "..\detailtabelle" WHERE e_key=%s',[DataSet.FieldByName('e_key').AsString]);
    ADOConnection1.Execute(sSQL, iRows);
    </pre&gt

    Comment


    • #3
      Lieber Andreas ich habe den falschen Code vom Anfänger forum kopiert, tut mir leid für deine Mühe!

      Also eigentlich wollte ich das er keinen Stammdatensatz löschen kann!!!

      das ist der richtige Code mit dem gleichen Problem!!

      <pre>
      procedure TForm1.KundenTableBeforeDelete(DataSet:TDataset);
      var aKey :String;
      FindQuery:TQuery;
      begin
      // Kunde der gelöscht wird
      aKey:=DataSet.FieldByName('e_key').AsString;
      // Suchabfrage generieren um die Datensätze zu lesen, bei denen
      // e_Key=aKey ist
      FindQuery:=TQuery.Create(Self);
      with FindQuery do
      try
      SQL.Add('SELECT e_key, COUNT(e_key) As Anzahl');
      SQL.Add('FROM "..\detailtabelle"');
      SQL.Add('GROUP BY e_key');
      SQL.Add('HAVING e_key=:findkey');
      Params[0].AsString:=aKey;
      Open;
      // überprüfen, ob überhaupt Daten gefunden wurden RecordCount=1;
      // theoretisch dürfte die Abfrage nur 1 Datensatz liefern)
      // und dann überprüfen, ob (Anzahl>0)
      if (RecordCount=1) then if (FieldByName('Anzahl').AsInteger>0) then
      begin
      ShowMessage('Kann nicht gelöscht werden...');
      // Löschen abbrechen
      SysUtils.Abort;
      end;
      finally
      Free;
      end; // with FindQuery
      end; // TForm1.KundenTableBeforeDelete
      </pre&gt

      Comment


      • #4
        Hallo,

        ich würde mich <b>niemals</b> auf eine vorherige SELECT-Abfrage verlassen, da es hier in jedem Fall ein ungesichertes Zeitfenster gibt. Dies gilt erst Recht bei einer ACCESS-Datenbank, da die JET ENGINE einen eigenen lokalen Cache verwendet und somit das Zeitfenster relativ gross wird.

        Statt dessen verlasse ich mich auf die referenzielle Integrität. Mit ACCESS 2000 habe ich dazu ein Beispielprojekt zusammengebaut: <br>
        a) ACCESS 2000-Datenbank <br>
        b) Tabelle MASTER <br>
        c) Tabelle DETAIL <br>
        d) MASTER und DETAIL werden im Dialog <b>Beziehungen bearbeiten</b> miteinander verbunden: Checkbox "Mit referenzieller Integrität" ankreuzen, aber keine Löschweitergabe

        Wenn nun im Delphi-Programm ein Datensatz aus MASTER gelöscht werden soll, dessen Primärschlüsselwert als Fremdschlüssel in DETAIL verwendet wird, legt die JET ENGINE automatisch ein Veto ein, so dass in der Anwendung eine Exception ausgelöst wird

        Comment


        • #5
          Das habe ich probiert!!

          Aber er läßt mich nur eine <b> normale </b> Beziehung aufbauen ohne Referentiellen Integrität, er schreibt mir das ich die Verknüpfung nicht machen kann weil ein anderer User( ich schätze mein Delphi erhebt anspruch auf die Tabellen) meine Tabelle sperrt.

          Wie gehe ich dann damit um????

          Comment


          • #6
            Hallo,

            bei derartigen Problemen ist es immer eine gute Idee, die Ursache Schritt für Schritt einzukreisen. Ich würde daher folgendes machen:<br>
            1. Mit ACCESS 2000 eine neue (lokale) Datenbank anlegen. <br>
            2. Mit ACCESS 2000 eine neue Tabelle anlegen, die einen Primärschlüssel verwendet. <br>
            3. Mit ACCESS 2000 eine weitere Tabelle anlegen, die eine Spalte für den Primärschüsselwert der anderen Tabelle vorsieht. <br>
            4. Im Dialog <b>Beziehungen</b> beide Tabellen über die gemeinsame Spalte verbinden und die Checkbox "Mit referenzieller Integrität" ankreuzen. <br>
            5. Innerhalb von ACCESS 2000 muss die referenzielle Integrität beim Löschversuch funktionieren. <br>
            6. Innerhalb von Delphi muss die referenzielle Integrität beim Löschversuch funktionieren.

            Wenn dies bei einer neuen Datenbank funktioniert, würde ich mir dann die Struktur der problematischen Datenbank genauer ansehen und den Fehler dort suchen

            Comment


            • #7
              Ich bekomme das nicht einmal bei einer neu erstellten Data.mdb hin, es kommt immer die gleiche Fehlermeldung das ein anderer Benutzer meine Data verwendet!!

              KOMISCH

              Comment


              • #8
                <b>HIHI!!</b>

                Also die Lösung glaubt mir keiner:

                Folgendes habe ich <b>VORHER</b> gemacht:

                Also <b>Tabelle im Entwurfsmodus geöffnet- dann auf Beziehungen</b>

                Und so <b>muß ich es machen</b> !!

                Keine Tabelle darf offen sein!

                In der <b>Menüleiste</b> gibt es auch eine <b>Option Beziehungen</b>

                Also Access wird mir immer unsympatischer (war es vorher auch!)

                BINE :_

                Comment


                • #9
                  Hab noch ein Problem bei der Umsetzung zwischen Tquery und TADOQuery

                  Bei folgenden Code bräuchte ich Hilfe:
                  <pre>
                  if findquerykunden_NR.value <>'' then
                  gehezu_combobox.items.add(findquerykunden_NR.value );
                  findquery.next;
                  end;
                  </pre&gt

                  Comment

                  Working...
                  X