MySql: Unterabfrage mit temporärer Tabelle simulieren
Andreas-Lindig
- datenbank
Hallo Forum,
Ich dreh durch!
Ich kriege keine Abfrage mit temporären Tabellen hin.
Bin ich zu blöd, oder ist das wegen Sommer oder was?
In mehreren MySql-Büchern (das arme Buchhandelspersonal muß die immer wieder einsortieren...)
steht folgendes:
//erzeugt eine temporäre Tabelle...
CREATE TEMPORARY TABLE tmp
//...füllt diese gleich mit Werten - entsprechende Spalten werden automatisch angelegt
SELECT meine_spalte, deine_spalte FROM meine_tabelle
//abfrage der temporären Tabelle mit irgendwelchen Bedingungen
SELECT * FROM tmp WHERE...
Ich habe oben bewusst eine ganz einfache - sinnlose Abfragefolge genommen,
weil es im Moment nur darum geht ÜBERHAUPT Daten von einer Tabelle in eine temporäre
Tabelle zu übertragen und diese dann abzufragen. Aber ich bekomme bei der letzten
Abfrage immer die Fehlermeldung, die Tabelle 'tmp' gäbe es nicht
("table 'meine_datenbank.tmp' doesn't exist").
Test1:
//keine Fehlermeldung
CREATE TEMPORARY TABLE tmp (meine_spalte INT(4))
//Fehlermeldung: "table 'tmp' already exists" DIE VORZEILE HAT ALSO FUNKTIONIERT!
CREATE TEMPORARY TABLE tmp (meine_spalte INT(4))
Test2:
//keine Fehlermeldung
CREATE TEMPORARY TABLE tmp (meine_spalte INT(4))
//keine Fehlermeldung FUNKTIONIERT ALSO!
DROP TABLE tmp
//Fehlermeldung: "unknown table 'tmp'" ES IST IN DER VORZEILE OFFENSICHTLICH ETWAS GELÖSCHT WORDEN!
DROP TABLE tmp
Fazit:
Die Tabelle wird angelegt und gelöscht - so wie geplant.
Aber warum kann man sie dann nicht abfragen?
Kann man sie denn in einem Client (bei mir MySql-Front) eigentlich sichtbar machen?
Wenn ich eine Tabelle OHNE TEMPORARY anlege, ist sie nach einer Neuverbindung sichtbar die tmp-Tabellen hingegen nicht.
Ich habe MySql 3.23.43 - also temporäre Tabellen sollten implementiert sein.
Was soll ich tun?
[] aufhängen?
[] ins Wasser gehen?
[] das Hobby wechseln?
[] sonstiges
(zutreffendes bitte ankreuzen)
Gruß und vielen Dank für Hilfe, Andreas
Moin!
Was soll ich tun?
[] aufhängen?
[] ins Wasser gehen?
[] das Hobby wechseln?
[x] sonstiges:
Beachte </faq/#Q-07b>.
Deine SQL-Statements sehen so verkürzt aus. Das ist sicherlich nicht das, was du tatsächlich vollständig an die Datenbank sendest. Und wenn doch, sieht es für mich trotzdem irgendwie unvollständig aus.
Was sagt mysql_error() zu deinen Versuchen?
- Sven Rautenberg
Moin!
Hallo
Deine SQL-Statements sehen so verkürzt aus.
verstehe ich nicht, Ich habe nicht mehr gemacht.
Das ist sicherlich nicht das, was du tatsächlich vollständig an die Datenbank sendest.
doch, natürlich mit anderen Tabellen und DB-Namen
Und wenn doch, sieht es für mich trotzdem irgendwie unvollständig aus.
hmm, ich geb' mir immer wirklich Mühe...
Was sagt mysql_error() zu deinen Versuchen?
Ich habe nur im MySql-Front getestet. Die Fehlermeldungen habe ich original aufgeschrieben - sind das nicht die gleichen, die auch mysql_error() ausgeben würde?
Gruß, Andreas
Moin!
Was sagt mysql_error() zu deinen Versuchen?
Ich habe nur im MySql-Front getestet. Die Fehlermeldungen habe ich original aufgeschrieben - sind das nicht die gleichen, die auch mysql_error() ausgeben würde?
Ja doch, klar. Sind dieselben.
//erzeugt eine temporäre Tabelle...
CREATE TEMPORARY TABLE tmp
//...füllt diese gleich mit Werten - entsprechende Spalten werden automatisch »» angelegt
SELECT meine_spalte, deine_spalte FROM meine_tabelle//abfrage der temporären Tabelle mit irgendwelchen Bedingungen
SELECT * FROM tmp WHERE...
Spannende Frage: Wo wird deine temporäre Tabelle mit Inhalt gefüllt? Sie einfach nur anzulegen reicht sicherlich nicht aus.
Ach, du hast das SELECT-Statement direkt hinter das CREATE geschrieben, um die Tabelle mit Inhalt zu füllen? Steht aber nicht so da.
CREATE TEMPORARY TABLE tmp SELECT spalte FROM tabelle
wäre irgendwie besser.
- Sven Rautenberg
Moin!
auch so,
steht aber nicht so da...
Ich habe mich bemüht, so gründlich wie möglich zu kommentieren, das reißt leider den Code auseinander...
also nochmal zusammenhängender:
//meine DB heißt forum, meine Tabelle forum_haupt
//erzeugt eine temporäre Tabelle und füllt sie mit Inhalt
CREATE TEMPORARY TABLE tmp
SELECT ID, Zeitpunkt FROM forum_haupt
//abfrage der temporären Tabelle
SELECT * FROM tmp
-> Fehlermeldung: "table 'meine_datenbank.tmp' doesn't exist")
Ich habe es auch mit CREATE und extra INSERT INTO tmp versucht - gleicher Fehler. Also habe ich einen Minimaltest versucht, um Fehler zu finden:
Test1 (kann man die tmp-Tabelle erzeugen?):
------------------------------------------
CREATE TEMPORARY TABLE tmp (meine_spalte INT(4))
-> keine Fehlermeldung, wiederhole das Statement:
CREATE TEMPORARY TABLE tmp (meine_spalte INT(4))
-> Fehlermeldung: "table 'tmp' already exists"
DAS ERSTE STATEMENT HAT ALSO FUNKTIONIERT!
Test2 (kann man die Tabelle tmp anlegen und löschen?):
-----------------------------------------------------
CREATE TEMPORARY TABLE tmp (meine_spalte INT(4))
-> keine Fehlermeldung
DROP TABLE tmp
-> keine Fehlermeldung FUNKTIONIERT ALSO! wiederhole zum Test dieses Statement:
DROP TABLE tmp
-> Fehlermeldung: "unknown table 'tmp'"
ES IST IM VOR-STATEMENT OFFENSICHTLICH ETWAS GELÖSCHT WORDEN!
Fazit:
-----
Die Tabelle wird angelegt und gelöscht - so wie geplant.
Aber warum kann man sie dann nicht abfragen, so wie ich es anfangs versucht habe?
Moin!
Fazit:
Die Tabelle wird angelegt und gelöscht - so wie geplant.
Aber warum kann man sie dann nicht abfragen, so wie ich es anfangs versucht habe?
Lass einfach mal das temporary weg. Es ist elementare Eigenschaft einer temporären Tabelle, dass sie gleich wieder gelöscht wird. Nämlich dann, wenn die Datenbankverbindung geschlossen wird.
Ich konnte deine Tests mit PHPMyAdmin aus genau diesem Grunde nicht nachvollziehen, weil PHPMyAdmin grundsätzlich bei jedem Seitenaufbau eine neue Datenbankverbindung herstellt. Entsprechendes könnte auch dir passieren - und sei es nur, wenn zum SELECTen eine andere Verbindung genutzt wird, als zum CREATEn und DROPpen.
Am schlauesten ist, wenn du dein Vorhaben mal zu etwas Code formst und damit die realen Verhältnisse in einem Programm simulierst. Dann siehst du vermutlich eher, was los ist.
- Sven Rautenberg
Lass einfach mal das temporary weg.
Dieses Verfahren wird aber überall mit tmp-Tabelle empfohlen, und zwar, weil die von anderen Usern nicht sichtbar ist. Wenn ich eine normale Tabelle anlege (das funktioniert übrigens) kann es sein, daß im selben Moment ein Anderer User die Gleiche Anfrage stellt und die - noch auszulesende - gerade angelegte Tabelle überschreibt. Das gibt doch völlig bananige Ergebnisse, oder?
Es ist elementare Eigenschaft einer temporären Tabelle, dass sie gleich wieder gelöscht wird. Nämlich dann, wenn die Datenbankverbindung geschlossen wird.
ach! - das heißt vielleicht, daß man in der ersten Abfragefoge gleich die Abfrage der tmp-Tabelle mitnehmen muß - das ging aus den Büchern nicht so klar hervor. Allerdings habe ich das auch schon probiert und eine Syntax-Fehler Meldung bekommen. naja, Du kennst die wahrscheinlich: `syntax-Error near: ... ' und dann wird fast die gesamte Abrage zitiert. Hmm...
...und sei es nur, wenn zum SELECTen eine andere Verbindung genutzt wird, als zum CREATEn und DROPpen
kann ich denn in PHP dann einfach die bisherige connect-ID immer wieder einsetzen, oder ist die nach einer Abfrage hinfällig? - bisher gebe ich immer gar keine connect-ID an. (ich kann im Moment nicht probieren, weil ich auf der Arbeit bin, deshalb frage ich schonmal)
Gruß, Andreas
Moin!
Lass einfach mal das temporary weg.
Dieses Verfahren wird aber überall mit tmp-Tabelle empfohlen, und zwar, weil die von anderen Usern nicht sichtbar ist.
Das weiß ich, steht ja in der Doku auch drin. Nur: Wenn es zu Testzwecken (und über die bist du ja noch nicht hinaus) ohne funktioniert, ist wenigstens der Rest nicht falsch, und die Probleme sind eindeutig auf das "temporary" zurückgeführt.
Es ist elementare Eigenschaft einer temporären Tabelle, dass sie gleich wieder gelöscht wird. Nämlich dann, wenn die Datenbankverbindung geschlossen wird.
ach! - das heißt vielleicht, daß man in der ersten Abfragefoge gleich die Abfrage der tmp-Tabelle mitnehmen muß - das ging aus den Büchern nicht so klar hervor. Allerdings habe ich das auch schon probiert und eine Syntax-Fehler Meldung bekommen. naja, Du kennst die wahrscheinlich: `syntax-Error near: ... ' und dann wird fast die gesamte Abrage zitiert. Hmm...
Schätzungsweise wird das deshalb nicht so ganz klappen, weil deine DB-Oberfläche vielleicht nur einen Abfragebefehl zur Zeit akzeptiert.
...und sei es nur, wenn zum SELECTen eine andere Verbindung genutzt wird, als zum CREATEn und DROPpen
kann ich denn in PHP dann einfach die bisherige connect-ID immer wieder einsetzen, oder ist die nach einer Abfrage hinfällig? - bisher gebe ich immer gar keine connect-ID an. (ich kann im Moment nicht probieren, weil ich auf der Arbeit bin, deshalb frage ich schonmal)
Genau so ist es. Einmal mysql_connect(), und die Connection dann immer weiter verwenden. An dieser Connection hängt nämlich so einiges. Zum einen die temporären Tabellen, die beim Schließen der Verbindung wieder gelöscht werden (also beim Skriptende, oder wenn du mysql_close() befiehlst), zum anderen beispielsweise mysql_insert_id() bzw. LAST_INSERT_ID().
- Sven Rautenberg
Schätzungsweise wird das deshalb nicht so ganz klappen, weil deine DB-Oberfläche vielleicht nur einen Abfragebefehl zur Zeit akzeptiert.
so ist es, und beim nächsten Mal öffnet Sie wahrscheinlich eine neue Verbindung. Du hast mir mit den verschiedenen Verbindungen den Entscheidenden Hinweis gegeben. Ich hab's gestern abend in PHP probiert, und es klappt!
danke schön, Andreas
--
http://extra.andeas-lindig.de/was_das/
Halihallo Andreas
so ist es, und beim nächsten Mal öffnet Sie wahrscheinlich eine neue Verbindung. Du hast mir mit den verschiedenen Verbindungen den Entscheidenden Hinweis gegeben. Ich hab's gestern abend in PHP probiert, und es klappt!
Neben den TEMPORARY kann ich noch http://www.mysql.com/doc/en/HEAP.html
Tables empfehlen. Die Funktionsweise ist etwa die selbe, nur, dass die Tabelle zwischen
den Clients geshared wird.
Viele Grüsse
Philipp
Hallo,
...dass die Tabelle zwischen den Clients geshared wird.
was heißt das denn - daß sie sichtbar für die anderen ist?
Halihallo Andreas
...dass die Tabelle zwischen den Clients geshared wird.
was heißt das denn - daß sie sichtbar für die anderen ist?
Genau... HEAP-Tables sind In-Memory-Tables, die solange am Leben bleiben wie der MySQL-
Server läuft und du die Tabelle nicht gelöscht hast. Die Tabelle wird zwischen allen
Clients geshared (eben sichtbar für alle aktiven Connections).
aus http://www.mysql.com/doc/en/HEAP.html:
"HEAP tables are shared between all clients (just like any other table)."
Viele Grüsse
Philipp