Hallo ihr lieben,
Ich muss in einem Vorgang circa 20 Tabellen löschen bzw. leeren.
Dies geschieht durch:
CurrentDb.Execute DELETE * From tbl1-20 usw.
Jetzt habe ich das Problem, dass die Tabellen so viele Datensätze haben, dass Access mir beim Löschen der 16. Tabelle ein Laufzeitfehler 3035 auswirft (Nicht genügend Systemressourcen - Arbeitsspeicher)
Diesen zu erhöhen ist keine Option.
Ich stelle diese Frage aus reiner Neugierde (ich möchte das Problem anders lösen und werde vermutlich da nochmal auf euch zurückkommen, wenn ich alleine nicht weiterkommen sollte).
Gibt es eine Möglichkeit Codezeilen mittendrin durch ein komprimieren zu unterbrechen und anschließend exakt dort fortzuführen? Ich habe bereits ein Beitrag von DonKarl gelesen, allerdings habe ich das so verstanden, dass ab AC03 sein Beitrag nicht mehr möglich sei?
http://www.donkarl.com?FAQ6.6 (http://www.donkarl.com?FAQ6.6)
Hallo,
nein, das ist nicht möglich. Beim Komprimieren wird die DB komplett geschlossen, komrimiert und dann wieder geöffnet.
PS:
Solche Tabellen gehören in ein separates Backend, das dann beim Schließen komprimiert wird. Dann dürfte sich das Problem erledigt haben.
Zitat von: MzKlMu am März 07, 2019, 12:35:14
PS:
Solche Tabellen gehören in ein separates Backend, das dann beim Schließen komprimiert wird. Dann dürfte sich das Problem erledigt haben.
Sind sie. Und das BE wird auch komprimiert beim schließen. Hätte ja sein können, dass es ein Trick 17 gibt. Schade! Danke für die schnelle Antwort.
Hallo!
Wenn der Code in einer anderen Datei ausgeführt wird, sollte das schon möglich sein: http://www.donkarl.com?FAQ6.7
Die Verbindung zum Backend sollte dann allerdings geschlossen sein.
zum Fehler "zu wenig Arbeitsspeicher":
Wie löscht du? Lässt du alles innerhalb einer Transaktion laufen?
Wäre es möglich, dass du statt dem Löschen der Datensätze die ganze Tabelle löscht und neu erstellst?
mfg
Josef
Zitat von: Josef P. am März 07, 2019, 13:11:49
zum Fehler "zu wenig Arbeitsspeicher":
Wie löscht du? Lässt du alles innerhalb einer Transaktion laufen?
Wäre es möglich, dass du statt dem Löschen der Datensätze die ganze Tabelle löscht und neu erstellst?
Was meinst du mit "Wie löscht du"?
Die Tabellen sind SQL Tabellen. Und in mein Access verknüpft.
Daher ist löschen und neu erstellen kein Weg für mich.
Ich hab aber ein kleinen "Schummelweg" gefunden.
Ich lösche 60% danach startet via VBA ne Batch die wider rum Access beendet, komprimiert und es wieder öffnet. Dadurch beginnt der Prozess zwar von vorne - da aber die Ersten 60% bereits gelöscht sind dauerts nur Sekunden bis er beim aktuellen Stand angekommen ist - mit komprimierter Datenbank.
Hallo!
"SQL-Tabelle" sind Tabellen im SQL-Server? ... dann lösch die Datensätze doch direkt per ADODB/OLEDB oder über eine PT-Abfrage im SQL-Server und nicht über die verknüpfte Tabelle.
ZitatWas meinst du mit "Wie löscht du"?
Auf welche Art du löscht. Löscht du per SQL-Anweisung (DAO oder ADODB), über das Docmd-Zeugs oder über ein Recordset.
mfg
Josef
Zitat von: Josef P. am März 07, 2019, 14:22:57
Hallo!
"SQL-Tabelle" sind Tabellen im SQL-Server? ... dann lösch die Datensätze doch direkt per ADODB/OLEDB oder über eine PT-Abfrage im SQL-Server und nicht über die verknüpfte Tabelle.
Sorry - meine Kenntnisse beschränken sich leider auf das nötigste. Ich muss diese Prozedur automatisiert durchlaufen lassen. Nachts. Und ja die Tabellen sind innerhalb eines SQL-Express Servers.
Zitat von: Josef P. am März 07, 2019, 14:22:57
Auf welche Art du löscht. Löscht du per SQL-Anweisung (DAO oder ADODB), über das Docmd-Zeugs oder über ein Recordset.
Ich lösche mit CurrentDB.Execute.
Kenne mich mit DAO oder ADODB leider überhaupt nicht aus.
CurrentDB.Execute ist DAO.
Zum Ausprobieren (Code gehört verbessert):
Bei dir sieht der Code aktuall vermutlich so ähnlich aus:
CurrentDB.Execute "delete from DeineTabelle"
Tausche diese Zeile zum Testen mit folgendem Code aus:
'CurrentDB.Execute "delete from DeineTabelle"
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.CreateQueryDef("")
qdf.ReturnsRecords = False
qdf.Connect = db.TableDefs("DeineTabelle").Connect
qdf.SQL = "delete from " & db.TableDefs("DeineTabelle").SourceTableName
qdf.Execute
qdf.Close
Damit wird mittels Pass-Through-Abfrage die Delete-Anweisung an den Server weitergegeben.
mfg
Josef
Josef P. Danke für diesen Hinweis.
Meine Frage hierzu wäre noch, da ich ja 20 Tabellen habe muss ich für jede Tabelle diesen Code ausführen ? oder reicht es wenn ich die Zeilen
qdf.Connect = db.TableDefs("DeineTabelle").Connect
qdf.SQL = "delete from " & db.TableDefs("DeineTabelle").SourceTableName
qdf.Execute
wiederhole jedoch immer mit anderen Tabellennamen?
So sozusagen :
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.CreateQueryDef("")
qdf.ReturnsRecords = False
qdf.Connect = db.TableDefs("DeineTabelle1").Connect
qdf.SQL = "delete from " & db.TableDefs("DeineTabelle1").SourceTableName
qdf.Execute
qdf.Connect = db.TableDefs("DeineTabelle2").Connect
qdf.SQL = "delete from " & db.TableDefs("DeineTabelle2").SourceTableName
qdf.Execute
qdf.Close
Wie geschrieben, der Code war nur zum Testen gedacht und gehört optimiert.
Beispiel (ungetester Luftcode, der nur das Prinzip zeigen soll):
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.CreateQueryDef("")
qdf.ReturnsRecords = False
qdf.Connect = db.TableDefs("DeineTabelle1").Connect ' oder fix den Connectionstring als Text übergeben
' da es immer die gleiche Datenbank sein wird, reicht es aus, die Connection nur einmal einzustellen
Dim TableNameArray() as variant
dim TabArrayItm as Variant
TableNameArray = Array("Tabelle1", "Tabelle2", ..., "Tabelle0815")
' oder gleich den Tabnamen vom SQL-Server verwenden:
' TableNameArray = Array("dbo.Tabelle1", "dbo.Tabelle2", ..., "dbo.Tabelle0815")
for each TabArrayItm in TableNameArray
qdf.SQL = "delete from " & db.TableDefs(TabArrayItm ).SourceTableName
' oder mit SQL-TabNamen: (läuft theoretisch schneller, da nicht auf die Access-Tabelle zugegriffen werden muss
' praktisch wird es nicht merkbar langsamer sein
'qdf.SQL = "delete from " & TabArrayItm
qdf.Execute
next
qdf.Close
Anm.: Ich würde diesen Code noch in Hilfsprozeduren aufteilen, aber das wird an dieser Stelle vielleicht zu unübersichtlich.
mfg
Josef
Vielen Dank für diese Hilfe bis hierhin. Ich werde es testen und Rückmeldung geben sobald ich was erreicht habe.
Es geht übrigens noch kürzer, da man per PT mehrere SQL-Anweisungen an den Server geben kann.
' 1. SQL-Anweisung zusammensetzen
Dim SqlText as String
Dim TableNameArray() as variant
dim TabArrayItm as Variant
TableNameArray = Array("Tabelle1", "Tabelle2", ..., "Tabelle0815")
' oder gleich den Tabnamen vom SQL-Server verwenden:
' TableNameArray = Array("dbo.Tabelle1", "dbo.Tabelle2", ..., "dbo.Tabelle0815")
for each TabArrayItm in TableNameArray
SqlText = SqlText & "delete from " & db.TableDefs(TabArrayItm ).SourceTableName & ";" & vbnewline
' oder mit SQL-TabNamen: (läuft theoretisch schneller, da nicht auf die Access-Tabelle zugegriffen werden muss
' praktisch wird es nicht merkbar langsamer sein
'SqlText = "delete from " & TabArrayItm & ";" & vbnewline
next
' 2. SQL-Anweisung ausführen
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb
Set qdf = db.CreateQueryDef("")
qdf.ReturnsRecords = False
qdf.Connect = db.TableDefs("DeineTabelle1").Connect ' oder fix den Connectionstring als Text übergeben
qdf.SQL = SqlText
qdf.Execute
Mit dieser Variante wird nur einmal eine Verbindung zum Server aufgebaut und die SQL-Anweisung übertragen.
Anm.: für den SQL-Server gibt es auch die Truncate (https://docs.microsoft.com/en-us/sql/t-sql/statements/truncate-table-transact-sql?view=sql-server-2017)-Anweisung zum Löschen aller Datensätze aus einer Tabelle.
mfg
Josef
ZitatIch muss in einem Vorgang circa 20 Tabellen löschen bzw. leeren.
Ich staune, dass das nicht schon an sich in Frage gestellt wird. Wenn man durch Löschen(!) an Kapazitätsgrenzen stößt wie auch immer, ist da m.M. im Umfeld etwas sehr misslungen und bedarf einer grundsätzlichen Analyse statt etwas Verarbeitungskosmetik.
Wenn der SQL Server Express am Limit ist, müsstest Du upgraden oder die Temp-Müll-Schleuder in ein eigenes Backend verlegen.
Könnte aber auch sein, dass man sich hier ein Frontend-Problem erzeugt hat. Da sollte man ebenso überprüfen, was man da tut.
Zitat von: sellrich am März 07, 2019, 12:29:28
Ich muss in einem Vorgang circa 20 Tabellen löschen bzw. leeren.
Ich stelle diese Frage aus reiner Neugierde (ich möchte das Problem anders lösen und werde vermutlich da nochmal auf euch zurückkommen, wenn ich alleine nicht weiterkommen sollte).
Auch an dem Punkt wieder mal vielen Dank für deine kritische und Lösungsorientierte Antwort. Zeigt einem sehr deutlich auf in was für einem Kauderwelsch von AccessKram ich mich hier bewegen muss ???
Das das keine Lösung ist ist mir durchaus bewusst. Wie bereits erwähnt, stelle ich diese Frage auch nur aus reiner Neugierde. Nur um rundum eben etwas mehr Kenntnisse zu erhalten.
Die Notwendigkeit des ständigen Löschen um ein sauberes neubefüllen zu gewährleisten ist auf dem "Mist" meines Vorgängers gewachsen.
Dies besser zu machen bzw. anders zu lösen liegt (noch!) nicht innerhalb meines Könnens.
Der Post von Josef zb. erweitert mein Kenntnisstand, da ich bisher noch nie mit Arrays gearbeitet habe und mich damit erstmal grundlegend befassen muss.
ZitatNotwendigkeit des ständigen Löschen um ein sauberes neubefüllen zu gewährleisten
Damit kannst Du dann nicht mehr sagen, Du hättest es nicht gewusst: Grundlagen - SQL ist leicht (4) - Aktualisierung einer Tabelle (https://www.ms-office-forum.net/forum/showthread.php?t=304156)
Zitat von: sellrich am März 08, 2019, 08:44:47
Die Notwendigkeit des ständigen Löschen um ein sauberes neubefüllen zu gewährleisten ist auf dem "Mist" meines Vorgängers gewachsen.
Unabhängig davon ob du in deiner Aussage recht hast, staune ich immer wieder wie Ahnungslose glauben in der Lage zu sein Code zu beurteilen.
Zufällig überarbeite ich auch grade ein Programm, bei dem das Gros der Tabelleninhalte zu Beginn der Verarbeitung gelöscht wird.
In meinem Fall ist aber auch der
einzig richtige Weg.
Ich wäre also vorsichtig mit deinen großspurigen Ansagen, so lange du noch völliger Anfänger bist - du wirst ja noch genug "Mist" produzieren und mangels Zeit nicht mehr ändern, wenn er denn funktioniert.
Lerne also ermal die Grundlagen damit du Zusammenhänge besser verstehst.
Nicht umsonst lernt man addieren vor dem dividieren.
ZitatIch wäre also vorsichtig mit deinen großspurigen Ansagen, so lange du noch völliger Anfänger bist - du wirst ja noch genug "Mist" produzieren und mangels Zeit nicht mehr ändern, wenn er denn funktioniert.
Ich denke, man kann durchaus bemerken, dass sich etwas falsch anfühlt (=> Empathie für Sachlage und Aufgabe), ohne jetzt augenblicklich genau zu wissen, warum das so ist und wie es konkret besser zu machen wäre. Insofern kann die "Großspurigkeit" auch einfach Realismus sein, losgelöst von einem vorhandenen Wissensniveau.
Sowie: Großspurigkeit ist nicht auf Neulinge beschränkt.
Zitat von: ebs17 am März 10, 2019, 13:46:37
Ich denke, man kann durchaus bemerken, dass sich etwas falsch anfühlt
So wie bei dir, wenn du über Dinge spottest die sich deinem Horizont entziehen.
Nein, das funktioniert nicht.
Zitatein sauberes neubefüllen
... möglich zu halten durch ein selektives Löschen, Editieren und Neuanfügen statt alles platt zu machen und von vorne aufzubauen und da Möglichkeiten und Wirkungen betrachten zu wollen ist eine Verengung des Horizontes?
Das muss man verstehen?
Wobei: Bei "alles platt machen" könnte man konsequent sein. Das temporäre Backend wäre ein Ansatz, der schon längst genannt wurde.
Zitatdass sich etwas falsch anfühlt
Das betrifft ja nun erst einmal Abläufe und Wirkungen an sich. Ob die mit einem supertollen Code umgesetzt sind und ob man diesen Code anfängerhaft noch nicht versteht, ist da weniger relevant.
Dass man in die Notwendigkeit kommt, mitten in der Verarbeitung komprimieren zu müssen, kann sich nicht als richtig anfühlen.
@markus888: Wer es nötig hat, fachliche Betrachtungen ins persönliche zu ziehen, der hat es nötig. Wer ist da komplexbehaftet?
Zitat von: markus888 am März 09, 2019, 13:41:09
Zitat von: sellrich am März 08, 2019, 08:44:47
Die Notwendigkeit des ständigen Löschen um ein sauberes neubefüllen zu gewährleisten ist auf dem "Mist" meines Vorgängers gewachsen.
Unabhängig davon ob du in deiner Aussage recht hast, staune ich immer wieder wie Ahnungslose glauben in der Lage zu sein Code zu beurteilen.
Ich wäre also vorsichtig mit deinen großspurigen Ansagen, so lange du noch völliger Anfänger bist - du wirst ja noch genug "Mist" produzieren und mangels Zeit nicht mehr ändern, wenn er denn funktioniert.
Lerne also ermal die Grundlagen damit du Zusammenhänge besser verstehst.
Nicht umsonst lernt man addieren vor dem dividieren.
Abgesehen vom "anprangern" meiner Menschlichkeit sehe ich in deinem Post keinerlei Relevanz die zum Lösen meines Problems beiträgt.
Ich würde eine solche Aussage nicht tätigen, wenn ich nicht exakt darüber im klaren bin, dass das nicht sauber gelöst ist. Mein "Vorgänger" und ich haben etliche Male über seine ehemaligen Projekte gesprochen und auch er nannte sich stets "Bastler".
Nur weil mir das Wissen fehlt, es besser zu machen bedeutet das nicht, dass ich nicht weiß das es möglich ist. Allein schon durch die Stunden um Stunden die ich damit verbracht habe etliche Threads in diesem Forum zu lesen, um erkennen zu können, dass es für fast alles ordentliche und saubere Lösungen gibt.
Und über deine Aussage "großspurige Ansage" solltest du eventuell nochmals nachdenken. War wohlmöglich nicht der netteste Satz der aus den Anschlägen deiner Tastatur entsprungen ist.
Zitat von: ebs17 am März 10, 2019, 13:46:37
Ich denke, man kann durchaus bemerken, dass sich etwas falsch anfühlt (=> Empathie für Sachlage und Aufgabe), ohne jetzt augenblicklich genau zu wissen, warum das so ist und wie es konkret besser zu machen wäre. Insofern kann die "Großspurigkeit" auch einfach Realismus sein, losgelöst von einem vorhandenen Wissensniveau.
Dem ist nichts hinzuzufügen.
Eine Frage wurde gestellt - es gab Antworten und eventuelle Verbesserungsvorschläge. Somit ist dieses Thema jetzt erledigt. Danke an alle produktiven Helfer!
@sellrich,
du kannst es drehen und wenden wie du willst.
Es war der Hinweise, dass es als Anfänger nicht angebracht ist vom "Mist" des Vorgängers zu reden.
Das wird auch in der Firma nicht gut ankommen.
Und das du das nicht gern hörst ist mir schon klar.
Ich habe keine andere Reaktion erwartet. Vom Eberhard schon gar nicht.
Ich bin da auch nicht besser.
Es hätte mich gewundert, wenn du da eine Sekunde nachdenken würdest.
Mist ist Mist, wenn es sich sachlich begründen lässt. Das auch unabhängig davon, ob der von einem Praktikanten oder einem alten Hasen erzeugt wurde.
Vermutlich hat jeder einige Dinge in seiner Vergangenheit, die er heute anders (=> besser!) lösen würde. Der alte Hase kann das auch problemfrei eingestehen, wenn ihn ein gesundes Maß an Selbstkritik und Lernfähigkeit durchs Leben tragen und er daneben auch einige Leistungen stehen hat, auf die er stolz sein kann, er also eine Lebensleistung hat, so dass er nicht seine Persönlichkeit und Selbstfindung an diesem einen Werk festmachen und jeden Ansatz von Kritik als Anpinkeln verstehen muss.