amstyles
Goto Top

SQL Statement Fehler Rückgabe in VBA

Hallo Foren User,

in einem SQL Statement lösche ich einen Datensatz aus einer Tabelle, die wiederum mit einer anderen verknüpft ist (Schlüssel).
Wenn dieser Eintrag nirgendwo referenziert ist, klappt das löschen ohne Probleme.
Jedoch wenn dieser auf eine andere Tabelle referenziert, dann müsste mir SQL einen Fehler zurückgeben.
Direkt auf dem SQL Server wird auch ein Fehler ausgegeben.

CurrentDb.Execute "DELETE FROM PRJVERWTSTADMIN_PRJV_PROJEKT WHERE PROJEKT = 'Projekt1"  
Kann man irgendwie mit OpenRecordset oder ähnlichem den SQL Fehler speichern?
Hierbei handelt es sich um Access 2007, VBA.

LG
AMStyles

Content-Key: 175449

Url: https://administrator.de/contentid/175449

Printed on: April 24, 2024 at 06:04 o'clock

Mitglied: 83928
83928 Oct 28, 2011 at 09:10:55 (UTC)
Goto Top
Hi,
(Du schon wieder (; )

Die allgemeine Fehlerbehandlung mit dem Err-Objekt sollte doch ausreichen. Oder sehe ich hier was falsch?


On Error Resume Next
CurrentDb.Execute ("delete * from tabellle1")  
If Err.Number <> 0 Then MsgBox Err.Description, , Err.Number
On Error GoTo 0
(allgemeines Beispiel)
Member: AMStyles
AMStyles Oct 28, 2011 at 09:21:03 (UTC)
Goto Top
Hallo abaaba,

ich habe es gerade ausprobiert, jedoch ohne Erfolg.
Er springt einfach nicht in das If rein...

AMStyles
Member: SlainteMhath
SlainteMhath Oct 28, 2011 at 09:32:01 (UTC)
Goto Top
Moin,

versuchs mal hiermit

 If DBEngine.Errors.Count > 0 Then
        For i = 0 To DBEngine.Errors.Count - 1
            msgbox DBEngine.Errors(i).Description & " in " & DBEngine.Errors(i).Source & " (" & DBEngine.Errors(i).Number & ")"  
        Next i
End If

lg,
Slainte
Member: AMStyles
AMStyles Oct 28, 2011 at 09:36:02 (UTC)
Goto Top
Servus,

da kommt die Meldung "Eigenschaft nicht gefunden. in DAO.Properties (3270).
Egal ob es funktioniert oder nicht.....

LG,
AMStyles
Member: SlainteMhath
SlainteMhath Oct 28, 2011 at 09:44:07 (UTC)
Goto Top
Aha.. .und wo? evtl gibts eine der Properties nicht (mehr - code is aus Access 2002) - Musst mal bischen testen.
Mitglied: 83928
83928 Oct 28, 2011 at 09:45:17 (UTC)
Goto Top
Was genau möchtest Du machen?
den SQL Fehler speichern?

Das ist ja mit leichter Abänderung der o.g. Zeilen möglich. Und was soll außerdem noch passieren?

Allgemeine Fehlerbehandlung würde ich zu den Grundlagen von VBA zählen, auch wenn es aufgrund der Eigenschaften dieser Sprache häufig ignoriert wird.
Mitglied: 83928
83928 Oct 28, 2011 at 09:48:51 (UTC)
Goto Top
ah, und wenn er nicht "ins IF springt" liegt es vermutlich daran das Du die On error resume next nicht ausführst.
Member: AMStyles
AMStyles Oct 28, 2011 at 11:51:50 (UTC)
Goto Top
Zitat von @83928:
Was genau möchtest Du machen?
> den SQL Fehler speichern?


ich habe eine Liste (Listenfeld), diese holt die Daten aus einer Tabelle, wenn ich in der Liste einen Eintag löschen möchte, wird im Hintergrund der komplette Datensatz gelöscht (Tabelle) jedoch passiert das nicht bei Einträgen, die wiederrum in einer anderen Tabelle benutzt werden. Das heißt, er läuft ganz normal durch, und zeigt am ende an, dass der Datensatz erfolgreich gelöscht wurde, obwohl der genau dies nicht kann, da auf SQL Ebene dieser Fehler passiert, wenn ich den Befehl im Management Studio ausführe.

In VBA möchte ich diesen Fehler abfangen, und wenn dieser geworfen wird, soll eine andere Meldung ausgegeben werden, als Datensatz erfolgreich gelöscht.
Member: AMStyles
AMStyles Oct 28, 2011 at 12:35:25 (UTC)
Goto Top
doch habs reinkopiert und das SQL Statement abgeändert
Member: SlainteMhath
SlainteMhath Oct 28, 2011 at 12:40:38 (UTC)
Goto Top
Also eigentlich wäre die saubere Methode eigentlich

1. Prüfen ob noch abhängige Datenseätze in anderen Tabelle vorhanden sind
2. Wenn nein => löschen
3. Wenn Ja => Fehler
Member: Biber
Biber Oct 28, 2011 at 15:06:52 (UTC)
Goto Top
Na ja, SlaintheMhath,

Zitat von @SlainteMhath:
Also eigentlich wäre die saubere Methode eigentlich

1. Prüfen ob noch abhängige Datenseätze in anderen Tabelle vorhanden sind
2. Wenn nein => löschen
3. Wenn Ja => Fehler

Noch eigentlicher wäre die sauberere Methode vorher mal einen Plan zu machen, wie der fachliche Zusammenhang und die Abhängigkeiten denn nun gestrickt werden sollen.

  • entweder es sollen alle abhängigen Child-Sätze gelöscht werden, wenn in der PRJVERWTSTADMIN_PRJV_PROJEKT ein Projekt gelöscht werden soll. Dann ist die FK-Constraint ein "ON DELETE CASCADE" und es gibt keinen Fehler.
  • oder es dürfen keine Sätze gelöscht werden, die Childsätze haben, weil die FK-Constraint "ON DELETE RESTRICT" ist. Dann kann ich, wenn ich doch weiss, dass es eh niemals nicht klappen kann, alle Sätze mit Childsätzen in einer passenden WHERE-Kalusel ausnehmen. Also ein LEFT JOIN mit der Childtabelle und "WHERE Childtab.Whatever IS NULL"
  • oder aber es dürfen keine Sätze in der PRJVERWTSTADMIN_PRJV_PROJEKT physikalisch gelöscht werden, sondern werden stattdessen logisch gelöscht (in einem Feld INAKTIV oder DELETED markiert.). Dann kann die FK-Constraint sein wie sie will bzw. wie sie grad zufällig definiert wurde.

Grüße
Biber
Member: SlainteMhath
SlainteMhath Nov 02, 2011 at 07:54:45 (UTC)
Goto Top
Moin Biber face-smile

natürlich kann ich alles per FK Contraints in die DB zementieren. Allerdings ist dann immer noch das Problem, dem User eine sinnvolle Fehlermeldung auszugeben. I.d.R. hilft dem Anwender ein "Kann nicht gellöscht werden, weil...." mehr als ein "ODBC Call falied -- FK Contraint violated..."

Und
ON DELETE CASCADE
mag ich persönlich nicht, weil u:u. ein DELETE ganze Tabellen oder gar Datanbanken leer macht (Alles schon gesehen face-smile ) jaja ich weis, auch das lässt sich durch Planung verhindern.

g,
Joerg
Member: Biber
Biber Nov 02, 2011 at 08:26:08 (UTC)
Goto Top
Moin SlaintheMhath,

ja nee, ich sehe es in diesem Fall nicht so, dass hier dem Endanwender eine sinnvolle Fehlermeldung helfen könnte.

Wie der viel zu früh verstummte Beitragsersteller geschrieben hat, ist der "Plan" doch, eine Batchverarbeitung, ein "DELETE... Where projekt ='XY'" auf Knopfdruck zu machen.

Dann kann ich sehr wohl im Konzept entscheiden, ob
  • das DELETE-Knöpfchen überhaupt angeboten wird, wenn Childsätze vorhanden sind
  • ob denn, wenn der befugte Anwender sagt "Dieses Projekt ist tot", auch alle Childsätze gelöscht werden, also die DB mit ON DELETE CASCADE hilft
  • und die allerallerallerunkomfortabelste Lösung ist, dem Endanwender zu sagen "Hey, du musst vorher alle Childsätze löschen, sonst geht nix."

Mein Kommentar oben sollte nur aussagen: "Menno, wenn jetzt beim Löschen eines Parent-Satzes erst über das Problem nachgedacht wird, dann ist es ein bisschen spät".

Grüße
Biber
Member: AMStyles
AMStyles Nov 02, 2011 at 09:17:31 (UTC)
Goto Top
Hallo Biber,

sorry, dass ich den "Plan" nicht richtig beschrieben habe.
Jetzt weiß ich zumindest worauf ich achten muss, jedoch noch keine Ahnung wie ich das Umsetzten kann (vom code her).
Die 3te Variante "und die allerallerallerunkomfortabelste Lösung ist, dem Endanwender zu sagen "Hey, du musst vorher alle Childsätze löschen, sonst geht nix."" würde mir sehr helfen.

Grüße,
AMStyles
Mitglied: 83928
83928 Nov 02, 2011 at 09:23:08 (UTC)
Goto Top
Die 3te Variante "und die allerallerallerunkomfortabelste Lösung ist, dem Endanwender zu sagen "Hey, du musst
vorher alle Childsätze löschen, sonst geht nix."" würde mir sehr helfen.

Des is a Witz, oder?
Member: AMStyles
AMStyles Nov 02, 2011 at 09:36:57 (UTC)
Goto Top
Zitat von @83928:

> Die 3te Variante "und die allerallerallerunkomfortabelste Lösung ist, dem Endanwender zu sagen "Hey, du musst
> vorher alle Childsätze löschen, sonst geht nix."" würde mir sehr helfen.

Des is a Witz, oder?

Nee, ich hab im moment keine Ahnung wie ich das Abfangen kann, dass geprüft wird, ob es entsprechende Datensätze gibt.
Mitglied: 83928
83928 Nov 02, 2011 at 09:51:35 (UTC)
Goto Top
Deine Planung scheint schwer verständlich. In den meisten Projektplanern ist es ja so, dass alle Childdatensätze eines Projekts 'automatisch' gelöscht werden, sobald das Projekt selber gelöscht wird -> Biber-Variante 2.
Es erschliesst sich nicht der Sinn, warum Du in diesem Fall eine Meldung ausgeben willst und was weiter passieren soll.....
Member: AMStyles
AMStyles Nov 02, 2011 at 10:08:30 (UTC)
Goto Top
Habe mir nochmals das Projekt angeschaut, und bin jetzt endgültig zum Entschluss gekommen, dass beide Varianten für mich Richtig sind.

Und zwar soll der Hinweis kommen "Es bestehen Childdatensätze, möchten Sie trotzdem das Projekt XY löschen?" mit den Buttons Ja, Nein.
Erst dann, soll bei "Ja" das Projekt komplett gelöscht werden mit Childsätze.

Grüße,
AMStyles
Mitglied: 83928
83928 Nov 02, 2011 at 10:23:20 (UTC)
Goto Top
Dann die Löschweitergabe einrichten (Biber-2-Variante) und vor der Delete-Abfrage mittels einer Select-Abfrage bestimmen, ob Childdatensätze vorhanden sind.

Und vorher vielleicht doch noch mal überlegen ob man den User mit sowas wie "Childdatensätze" behelligen möchte oder ob nicht allgemein die Frage reicht: "Möchten Sie das Projekt wirklich löschen? Ja/Nein" - unabhängig davon ob Child- DS existieren oder nicht.

Gruß
Member: AMStyles
AMStyles Nov 02, 2011 at 10:26:58 (UTC)
Goto Top
ok und wie richte ich dies ein?
Mir ist nicht ganz Klar, wie ich das in VBA umsetzten könnte.

Grüße & Danke,
AMStyles
Mitglied: 83928
83928 Nov 02, 2011 at 11:48:39 (UTC)
Goto Top
Du musst nicht viel in VBA machen! Das Löschen der Child-DS übernimmt Dein Backend - sofern eingerichtet ("ON DELETE CASCADE")

und der VBA-Teil sieht dann ungefähr so aus:

If MsgBox("soll das Projekt gelöscht werden?", vbYesNo) = vbYes Then _  
    CurrentDb.Execute "DELETE FROM PRJVERWTSTADMIN_PRJV_PROJEKT WHERE PROJEKT = '" &  strProjektName "'"