Autor Beitrag
thomasoop
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mo 09.02.09 17:59 
Hallo zusammen,
ich würde gerne eine Reihe von Abfragen die sich in einer Access MDB befinden ausführen.
Wenn die Abfrage ein select ist, kann ich die Abfrage in Delphi über eine Query als Normale Tabelle ansprechen.

z.b. query1.sql.text := 'select * from abfrage'.

Wie aber führe ich Löschabfragen aus oder lese diese alternativ aus damit ich sie mit einer Query per ExecSQL ausführen kann?
Wenn ich ein ausführen versuche kommt die Fehlermeldung:
Zitat:
Fehler: Indexfehler
[Microsoft][ODBC Microsoft Access Driver] Eine Aktionsabfrage kann nicht als Quelle für eine Zeile verwendet werden.


Wäre euch für Hilfe dankbar, ich teste hier schon rauf und runter ohne wirklich weiter zu kommen.

Viele Grüße
Thomas
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 09.02.09 18:09 
Bei welchem Quelltext und welcher SQL-Abfrage kommt diese Fehlermeldung?

Ins Blaue geschossen: Das hört sich so an als würdest du die Abfrage zur Bestimmung der zu löschenden Daten falsch machen.
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mo 09.02.09 18:13 
Ich hab die Löschabfrage 0000_XXXX und 0000_YYYYY

Über den Systemkatalog les ich die Löschabfragenamen aus.
Danach möchte ich die Löschabfragen über Delphi ausführen(ich möchte kein "Delete ..." ausführen sondern den Inhalt einer Löschabfrage in Access.
Hintergrund ist, das ich dann die Löschabfragen ändern kann ohne das Programm neu compilieren zu müssen.

Die Löschabfragen lassen sich übrigens ohne Probleme in Access ausführen.

Hoffe die Erklärung ist verständlich.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
  With q__Arb1 Do
  Begin
    Close;
    SQL.Text := 'select name from MSysObjects where name like ''0000%'' order by name';
    Open;
    While not eof Do
    Begin
      zlvArbe := FieldValues['name'];
      With q__Arb2 Do
      Begin
        Close;
        SQL.Text := 'select * from [' + zlvArbe + ']';
//        t__Arb1.TableName := zlvArbe;
        Try
//          t__Arb1.Open;
          ExecSQL;
        Except
          On E : Exception Do
          Begin
            mpoLog.Lines.Add ( 'Abfrage: ' + zlvArbe );
            mpoLog.Lines.Add ( 'Fehler: ' + E.Message );
            Exit;
          End;
        End;
        Close;
      End;
    End;
    Close;
  End;


Moderiert von user profile iconNarses: Code- durch Delphi-Tags ersetzt
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 09.02.09 18:17 
Verstehe ich das richtig, Du hast DML als Feldinhalt innerhalb der DB? Wenn ja, kannst Du das dann doch einfach dem SQL.Text einer Query zuweisen.
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mo 09.02.09 18:25 
user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
Verstehe ich das richtig, Du hast DML als Feldinhalt innerhalb der DB? Wenn ja, kannst Du das dann doch einfach dem SQL.Text einer Query zuweisen.

Ich bin nicht sicher ob ich verstanden habe was du meinst.

Ich habe eine Systemtabelle, dort stehen (u.a.) alle Abfragenamen drin.
Zusätzlich habe ich Löschabfragen deren inhalt folglich ein "delete ...." ist.

Nun lese ich alle von mir gewünschten Abfragenamen aus der Systemtabelle aus.
Diese (Lösch)abfragen möchte ich danach ausführen.
Zugegeben mein Versuch dies über ein "select * from löschabfrage" zu bewerkstelligen ist schon stümperhaft aber ich wusste nicht so genau wo ich ansetzen sollte.

Ich habe aber nicht das SQL respetive die "Delete ..." Anweisungen in einer Tabellenspalte sondern in den einzelnen Löschabfragen.
Diese möchte ich ausführen oder wahlweise auslesen um sie danach direkt in Delphi ausführen zu können.

Das Ausführen habe ich ja schon versucht (siehe Codebeispiel).
Die Alternative wäre ein auslesen der Access Abfrage in Delphi.

Z.b. so

- lese Abfragenamen
- gehe von erster bis letzter gefundenen Abfrage durch
- lese abfrage inhalt ("delete ...")
- führe abfrageinhalt als sql per query1.execsql aus ("delete ...").
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 09.02.09 18:32 
Ja eben. Du holst Dir Deine Datenmenge, gehst diese durch, weist einer 2. Query den ausgelesenen String als SQL.Text zu und führst es aus.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
QueryHolen.SQL.Text := 'SELECT DMLString FROM Tabelle';
QueryHolen.Open;
while not QueryHolen.EOF do
  begin
    QueryLoeschen.SQL.Text := QueryHolen.FieldByName('DMLString').Value;
    QueryLoeschen.ExecSQL;
    QueryHolen.Next;
  end;

So in der Art stelle ich mir das vor.
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mo 09.02.09 19:29 
user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
Ja eben. Du holst Dir Deine Datenmenge, gehst diese durch, weist einer 2. Query den ausgelesenen String als SQL.Text zu und führst es aus.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
QueryHolen.SQL.Text := 'SELECT DMLString FROM Tabelle';
QueryHolen.Open;
while not QueryHolen.EOF do
  begin
    QueryLoeschen.SQL.Text := QueryHolen.FieldByName('DMLString').Value;
    QueryLoeschen.ExecSQL;
    QueryHolen.Next;
  end;

So in der Art stelle ich mir das vor.

ok moment, ich glaub das verwirrt jetzt was
ich versuch mein problem aufs wesentliche zu begrenzen(da ich das Gefühl habe wir reden einander vorbei).

das was du vorhast wird leider nicht gehen da mein "delete" SQL nicht in einer Tabellenspalte sondern in einer Löschabfrage in access ist.

Vergess bitte diesen Kram mit der MSysObjects.

Ich habe eine Löschabfrage in Access die ich von Delphi heraus ausführen möchte.
In dieser Löschabfrage steht ein X-beliebiges SQL.
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 09.02.09 19:35 
Da ich von Access keine blassen Schimmer habe: ist diese "Löschabfrage" so etwas wie eine Stored Procedure, d.h. eine ausführbare Anweisung des DBMS?
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mo 09.02.09 19:47 
user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
Da ich von Access keine blassen Schimmer habe: ist diese "Löschabfrage" so etwas wie eine Stored Procedure, d.h. eine ausführbare Anweisung des DBMS?

oh okay das ist natürlich nicht so gut *g
aber ja genau so ist es. eine abfrage in access speichert nur eine SQL anweisung
wenns ein select ist, kann es als view verwendet werden
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mo 09.02.09 19:54 
Nach einer kurzen Suche bin ich auf diese Seite gestoßen, vielleicht hilft Dir das schon ein wenig. So wie sich das liest, könntest Du aus einer Query heraus "exec Abfragename Parameterliste" aufrufen.
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mo 09.02.09 20:05 
user profile iconDeddyH hat folgendes geschrieben Zum zitierten Posting springen:
Nach einer kurzen Suche bin ich auf diese Seite gestoßen, vielleicht hilft Dir das schon ein wenig. So wie sich das liest, könntest Du aus einer Query heraus "exec Abfragename Parameterliste" aufrufen.

Sowas in der Art habe ich auch schon gefunden. Aus VBA heraus scheint das auch prima zu klappen nur ist mir bisher nicht die adaptierung auf Pascal gelungen. Ich werde mich damit aber weiter beschäftigen! Danke für den Ansatz.
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Di 10.02.09 13:18 
Ich schon wieder :-)

Mein nächster Lösungsversuch war die Benutzung der Komponennte TStoredProc.

ausblenden Quelltext
1:
2:
StoredProc1.StoredProcName := "0000_Loesche_alles";
StoredProc1.ExecProc;


0000_Loesche_alles ist hier die Löschabfrage in Access.
Leider bleibt das Programm hier einfach nur hängen(ohne Exception).
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 10.02.09 18:26 
Was mich ein wenig wundert ist die Tatsache, dass eine Query mit "exec Bla" unter VBA ja anscheinend funktioniert, unter Delphi mit einer Query aber nicht. Es könnte natürlich sein, dass der ADO-Layer das irgendwie umformt. Ich habe dazu noch diesen Thread gefunden, da die Lösung aber dort nicht gepostet wird, ist das leider auch nicht zielführend.

[edit] Du meinst aber sicher TADOStoredProc und nicht TStoredProc, oder? [/edit]
Ydobon
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 42



BeitragVerfasst: Di 10.02.09 19:34 
Ich schaffe es nicht, das Problem nachzuvollziehen. Hast du mal eine Beispieldatenbank?
ausblenden Delphi-Quelltext
1:
2:
  ADOQuery1.SQL.Text:='exec 0000_Loesche_alles;';
  ADOQuery1.ExecSQL;
funktioniert ohne jedes Meckern. Obwohl vermutlich direkt TADOConnection oder TADOCommand eher dafür gedacht wären.
DeddyH
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 10.02.09 19:54 
Ich hab auch die ganze Zeit gedacht, es ginge um ADO, bis ich mir die Fehlermldung genauer angeschaut habe :oops:
thomasoop Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 29


D5 + D6 Enterprise
BeitragVerfasst: Mi 18.02.09 13:07 
user profile iconYdobon hat folgendes geschrieben Zum zitierten Posting springen:
Ich schaffe es nicht, das Problem nachzuvollziehen. Hast du mal eine Beispieldatenbank?
ausblenden Delphi-Quelltext
1:
2:
  ADOQuery1.SQL.Text:='exec 0000_Loesche_alles;';
  ADOQuery1.ExecSQL;
funktioniert ohne jedes Meckern. Obwohl vermutlich direkt TADOConnection oder TADOCommand eher dafür gedacht wären.

Es geht um eine ganz normale TQuery und TStoredProc.

An TADOQuery hab ich noch garnicht gedacht bzw. kannte das bis grad nicht.
Ich teste das mal, gut möglich das damit alle Problem gelöst sind.
Melde mich wieder!