Multiple SQL Querys auf einmal?

In diesem Forum gibt es Starthilfe zum neuen Extension-System von phpBB 3.1/3.2. Fragen zur Entwicklung von Extensions und zur Konvertierung von phpBB 3.0.x MODs sind ebenfalls willkommen.
Benutzeravatar
LukeWCS
Supporter
Supporter
Beiträge: 2089
Registriert: 15.12.2014 10:19
Kontaktdaten:

Multiple SQL Querys auf einmal?

Beitrag von LukeWCS »

Hallo Kollegen

Ich benötigte für LFWWH eine Funktion zum reindizieren einer Tabelle mit anschliessender Zurücksetzung des auto_increment Wertes. Den dafür nötigen SQL Code habe ich zusammen, dass ist nicht das Problem. Mir geht es darum zu verhindern, dass während dieser Aktion ein anderer SQL Query reingrätscht. Der SQL Code besteht aus 3 einzelnen Querys und ich muss irgendwie sicherstellen, dass weitere Querys auf meine Tabelle erst dann wieder ausgeführt werden dürfen, wenn meine 3 Querys am Stück erledigt wurden. Denn sonst ist meine Aktion komplett unnütz, wenn währenddessen ein neuer Record hinzugefügt wird.

Nun kann mit sql_query() leider immer nur ein einzelner SQL Query abgesetzt werden, nicht mehrere. Gibt es dafür eine Lösung? In der Klassen Doku habe ich dazu nichts gefunden und auch nicht bei den Exts in meinem Archiv. Ich schätze das ist einfach zu "speziell".
Möge das Backup mit dir sein. Immer.

Erweiterungen - Infos zur artgerechten Haltung
phpBB Ext Check - Analysesystem für phpBB Erweiterungen (Entwickler Werkzeug)
posaunen
Mitglied
Beiträge: 402
Registriert: 21.04.2004 20:05

Re: Multiple SQL Querys auf einmal?

Beitrag von posaunen »

Unter MySQL kann man Tabellen sperren - lock tables.
69bruno
Mitglied
Beiträge: 444
Registriert: 05.06.2020 08:21

Re: Multiple SQL Querys auf einmal?

Beitrag von 69bruno »

Soll das Bestandteil der Ext werden ?
Forum: cruiser-lounge.de
PHPBB-Version: 3.3.11 / Debian-Linux 10 / PHP-Version: 8.1
Benutzeravatar
LukeWCS
Supporter
Supporter
Beiträge: 2089
Registriert: 15.12.2014 10:19
Kontaktdaten:

Re: Multiple SQL Querys auf einmal?

Beitrag von LukeWCS »

posaunen hat geschrieben: 25.09.2021 15:16 Unter MySQL kann man Tabellen sperren - lock tables.
Darüber bin ich bei meiner Suche auch schon gestolpert, dass ist jedoch nicht ganz unproblematisch. Wenn dann bei meiner Aktion etwas schiefgeht, wird das abschliessende UNLOCK TABLES eventuell nicht ausgeführt. Und das kann Nebeneffekte haben, wie ich festgestellt habe:
Allgemeiner Fehler
SQL ERROR [ mysqli ]

Table 'phpbb_config_text' was not locked with LOCK TABLES [1100]

SQL

SELECT * FROM phpbb_config_text WHERE config_name = 'reparser_resume'

BACKTRACE
Das interessante ist; mit dieser Tabelle habe ich zumindest bei meiner Ext nichts zu tun.
69bruno hat geschrieben: 25.09.2021 15:50 Soll das Bestandteil der Ext werden ?
Wenn ich das Problem wirklich sauber lösen kann: ja, auf jeden Fall.
Möge das Backup mit dir sein. Immer.

Erweiterungen - Infos zur artgerechten Haltung
phpBB Ext Check - Analysesystem für phpBB Erweiterungen (Entwickler Werkzeug)
Benutzeravatar
chris1278
Mitglied
Beiträge: 3526
Registriert: 12.11.2007 06:20
Wohnort: Euskirchen
Kontaktdaten:

Re: Multiple SQL Querys auf einmal?

Beitrag von chris1278 »

Ich bin jetzt zwar nicht gerade der experte was SQL und sonstiges angeht, aber mal blöd gefragt wenn du die wwh Tabelle sperrst müsstest du ja auch irgendwie die kommenden abfragen dazu abfangen und zwischenspeichern. Also wenn jetzt jemand da war und das in die Tabelle eingetragen werden soll währen du diese eben kurzzeitig gesperrt hast.
69bruno
Mitglied
Beiträge: 444
Registriert: 05.06.2020 08:21

Re: Multiple SQL Querys auf einmal?

Beitrag von 69bruno »

Da käme mir die Idee, die Tabelle entweder zu duplizieren, im Duplikat zu arbeiten und nach Durchlauf das Original zu überschreiben, oder (hier weiß ich nur nicht, ob es geht) sie als recordset im Speicher zu manipulieren und nach Änderung zurückzuschreiben.
Forum: cruiser-lounge.de
PHPBB-Version: 3.3.11 / Debian-Linux 10 / PHP-Version: 8.1
Benutzeravatar
LukeWCS
Supporter
Supporter
Beiträge: 2089
Registriert: 15.12.2014 10:19
Kontaktdaten:

Re: Multiple SQL Querys auf einmal?

Beitrag von LukeWCS »

chris1278 hat geschrieben: 25.09.2021 16:27 Ich bin jetzt zwar nicht gerade der experte was SQL und sonstiges angeht, aber mal blöd gefragt wenn du die wwh Tabelle sperrst müsstest du ja auch irgendwie die kommenden abfragen dazu abfangen und zwischenspeichern. Also wenn jetzt jemand da war und das in die Tabelle eingetragen werden soll währen du diese eben kurzzeitig gesperrt hast.
Für diese Problematik hat MySQL bereits einen Mechanismus um konkurrierende SQL Querys abzuarbeiten. Diese werdend der Reihe nach ausgeführt, wie mir Mahony vor kurzem betätigt hat.

Das zwischenspeichern müsste logischerweise so aussehen, dass ich die Daten dann in einer zweiten Tabelle ablege. Das ist keine Option für mich.
69bruno hat geschrieben: 25.09.2021 16:29 Da käme mir die Idee, die Tabelle entweder zu duplizieren, im Duplikat zu arbeiten und nach Durchlauf das Original zu überschreiben, oder (hier weiß ich nur nicht, ob es geht) sie als recordset im Speicher zu manipulieren und nach Änderung zurückzuschreiben.
Der Gedanke klingt erstmal gut, aber:
und nach Änderung zurückzuschreiben
Dabei habe ich dann exakt die gleiche Problematik. Denn zu diesem Zeitpunkt des Zurückschreibens müsste ich ja ebenfalls konkurrierende Schreibzugriffe "ausbremsen/zurückhalten".
Möge das Backup mit dir sein. Immer.

Erweiterungen - Infos zur artgerechten Haltung
phpBB Ext Check - Analysesystem für phpBB Erweiterungen (Entwickler Werkzeug)
69bruno
Mitglied
Beiträge: 444
Registriert: 05.06.2020 08:21

Re: Multiple SQL Querys auf einmal?

Beitrag von 69bruno »

Beim Einlesen die Anzahl Datensätze zählen und vor dem zurückschreiben erneut zählen. Sind sie gleich, überschreiben. Sind sie unterschiedlich, Prozedur neu starten.

Nachtrag:
Oder hinzugekommene DS anhängen
Forum: cruiser-lounge.de
PHPBB-Version: 3.3.11 / Debian-Linux 10 / PHP-Version: 8.1
Benutzeravatar
oxpus
Ehemaliges Teammitglied
Beiträge: 5386
Registriert: 03.02.2003 12:33
Wohnort: Bad Wildungen
Kontaktdaten:

Re: Multiple SQL Querys auf einmal?

Beitrag von oxpus »

Dass jemand anders in die Datenbank speichert, kann man nur mit Zugriffsrechten verhindern.

Wenn es aber darum geht, den eigenen "Zyklus" unbehindert durchzuführen, wären die Befehle $db->sql_transaction('begin');
am Anfang und $db->sql_transaction('commit'); am Ende des gesamten Blocks hilfreich.
Dann werden alle Aktionen nacheinander ohne die Möglichkeit von äußeren Störungen ausgeführt.

Allerdings verhindert das wie gesagt nicht, das bis zur ersten auszuführenden SQL-Anweisung bereits jemand anders in der Datenbank etwas ändert.
Daher wäre es ratsam, die SQL-Anweisungen im Programmablauf so zu formulieren, das sie mit dem vorhandenen Ergebnis arbeiten und nicht erst Daten ausliest, verarbeitet und erst danach die Änderungen in die Datenbank zurückschreibt.

Wenn es Dir aber nur um den neuen Aufbau eines Tabellen-Indexes geht, kannst Du mit $db->sql_index_drop(); den Index löschen
und mit $db->sql_create_primary_key(); selbigen wieder aufbauen.
Den Rest erledigt dann die Datenbank alleine, auch den Stopp aller anstehenden Schreibzugriffe.
Grüße
OXPUS
Kein Support bei unaufgeforderten PNs, E-Mails oder auf anderem Weg!!
Benutzeravatar
LukeWCS
Supporter
Supporter
Beiträge: 2089
Registriert: 15.12.2014 10:19
Kontaktdaten:

Re: Multiple SQL Querys auf einmal?

Beitrag von LukeWCS »

69bruno hat geschrieben: 25.09.2021 17:06 Beim Einlesen die Anzahl Datensätze zählen und vor dem zurückschreiben erneut zählen. Sind sie gleich, überschreiben. Sind sie unterschiedlich, Prozedur neu starten.
Das ist nicht ganz so simpel, weil in der Tabelle ständig Bewegung ist. Die Tabelle kann je nach Besucher-Situation zwischen 1 und x Records enthalten und veraltete Einträge werden gelöscht. Die Tabelle enthält also keine statischen Datensätze bei denen nur neue dazu kommen würden, sondern eine dynamische Abbildung der Besucher-Situation bei der Records hinzugefügt, geändert und gelöscht werden.
oxpus hat geschrieben: 25.09.2021 18:43 Wenn es aber darum geht, den eigenen "Zyklus" unbehindert durchzuführen, wären die Befehle $db->sql_transaction('begin');
am Anfang und $db->sql_transaction('commit'); am Ende des gesamten Blocks hilfreich.
Crizzo hat mich zwischenzeitlich auch auf diese Funktion hingewiesen. Allerdings war nicht klar, ob die Querys innerhalb eines Transaction Blocks tatsächlich am Stück ausgeführt werden und solange alle anderen Schreibzugriffe auf die Tabelle pausiert sind.
Dann werden alle Aktionen nacheinander ohne die Möglichkeit von äußeren Störungen ausgeführt.
Okay, das wäre ganz exakt das was ich suche. Das heisst wenn während der Ausführung der 3 Querys andere Schreibzugriffe auf die Tabelle eintreffen würden, dann würden diese erst ausgeführt werden, wenn der Transactions Block erledigt ist?
Allerdings verhindert das wie gesagt nicht, das bis zur ersten auszuführenden SQL-Anweisung bereits jemand anders in der Datenbank etwas ändert.
Daher wäre es ratsam, die SQL-Anweisungen im Programmablauf so zu formulieren, das sie mit dem vorhandenen Ergebnis arbeiten und nicht erst Daten ausliest, verarbeitet und erst danach die Änderungen in die Datenbank zurückschreibt.
Die Daten selbst wären in dem Fall nicht von Interesse. Die Records sollen bleiben wie sie sind, es soll einfach nur der Index aller Records neu aufgebaut werden, beginnend bei 1. Sobald das erledigt ist, kann ich auto_increment auf 1 setzen, wodurch es von MySQL automatisch auf die letzte Record Nummer plus 1 gesetzt wird.
Wenn es Dir aber nur um den neuen Aufbau eines Tabellen-Indexes geht, kannst Du mit $db->sql_index_drop(); den Index löschen
und mit $db->sql_create_primary_key(); selbigen wieder aufbauen.
Den Rest erledigt dann die Datenbank alleine, auch den Stopp aller anstehenden Schreibzugriffe.
Klingt ebenfalls interessant. Hab etwas gebraucht bis ich herausfand wie ich das einbinden muss, damit ich diese beiden Funktionen nutzen kann. Problem ist jedoch, ich weiss nicht was da bei $index_name erwartet wird. Ich bin vom Spaltenname des Indexes ausgegangen, aber das scheint es wohl nicht zu sein: "Can't DROP 'wwh_id'; check that column/key exists [1091]". Die Doku ist hier leider auch null hilfreich und ich fand bei mir auch keine Ext die $db->sql_index_drop(); nutzen würde.

Was das angeht, tappe ich also noch im dunkeln. Aber mir wäre die Transactions Methode eh wesentlich lieber, weil ich dadurch auch gleich generell eine Lösung für bestimmte andere Probleme hätte.
Zuletzt geändert von LukeWCS am 25.09.2021 20:43, insgesamt 1-mal geändert.
Möge das Backup mit dir sein. Immer.

Erweiterungen - Infos zur artgerechten Haltung
phpBB Ext Check - Analysesystem für phpBB Erweiterungen (Entwickler Werkzeug)
Antworten

Zurück zu „Extension Bastelstube“