Zum Inhalt springen

2 DB-Tabellen gleichzeitig auslesen?

Erstellt am 8. September 2009 · 9 Antworten · letzte Antwort am 16. September 2009

Tags: PHP, Datenbank, Frage

saltletts ·

Hallo,

Ich kassier sicher gleich ein Riesengelächter, wenn ich sage ich will eine Extension anfertigen, und hab von PHP nur bedingt Ahnung. Aber ist nur ein kleines Vorhaben, und habs eigentlich auch schon fast. Aber nur "fast"....

Das Problem ist, ich muss im gleichen Atemzug mit dem Auslesen von tt_address, noch auf eine weitere DB-Tabelle zugreifen. Und zwar muss ich country mit einer Spalte aus dieser anderen Tabelle abgleichen, bzw. den Inhalt auslesen. Dadurch ergäbe sich dann eine Ländervorwahl (diese weitere DB-Tabelle enthält diese ganzen Ländervorwahlen).

Ich kann jetzt nen neuen Query anlegen und nenne ihn $res2:

$res2 = $GLOBALS['TYPO3_DB']->exec_SELECTquery ('*','laendervorwahlen', 'lvorwahl='.$country[$zaehler]);

Aber sobald ich die Tabelle auslese:

$row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res2)

gibts nen krassen Fehler. So von wegen das der Header schon gesendet wurde.

Wie komme ich denn jetzt an meine Variable $lvorwahl? Wie greife ich parallel die zweite DB-Tabelle ab? Das muss da hin wo: ######HIER##### steht.

	function getAddressData()
	{
		$user_id = $GLOBALS['TSFE']->fe_user->user[uid];
		
		// Select Query bilden
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery ('*','tt_address', 'pid='.$user_id);
		$zaehler = 0;	
		
		while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
			$zaehler++;		
			$name[$zaehler] = $row['name'];
			$vorwahl[$zaehler] = $row['vorwahl'];	
			$nummer[$zaehler] = $row['nummer'];
			$country[$zaehler] = $row['country'];	

                        ######HIER######

			$zeile[$zaehler]='		
				<form name="*******" method="post" action="**********">			
					<tr>
						<td align="center">
							'.$name[$zaehler].'
							<input type="hidden" name="name" value="'.$name[$zaehler].'" />            
						</td>
						<td align="center">
							'.$vorwahl[$zaehler].'
							<input type="hidden" name="vorwahl" value="'.$vorwahl[$zaehler].'" />            
						</td>
						<td align="center">
							'.$nummer[$zaehler].'
							<input type="hidden" name="nummer" value="'.$nummer[$zaehler].'" />            
						</td>
						<td align="center">
							'.$country[$zaehler].'
							<input type="hidden" name="country" value="'.$country[$zaehler].'" />            
						</td>
						<td align="center">
							'.$lvorwahl[$zaehler].'
						</td>
						<td align="center">
							'.$zaehler.'
							<input type="submit" name="button" value="Eine SMS senden" />
						</td>
					</tr>
				</form>						
			';
			$content = $content . $zeile[$zaehler];
		}
		$content = $content . '				
				</tbody>
			</table>			
		';				

		return $content;		
	}
marksta ·

Hallo Saltletts

Als erstes war ich erstaunt über deine erste Query. Du lädst alle Adressen, welche auf der Seite sind, welche die gleiche Page-Uid haben, wie die User-Uid des aktuellen Benutzers. Naja, sowas kanns ja geben. 🙂

Aber um dem Fehler auf den Grund zu gehen empfehle ich im InstallTool das sqlDebug auf 1 zu setzten, dann bekommst Du (hoffentlich) eine genaue Fehlermeldung.

Oder versuchs mal so:

echo $GLOBALS['TYPO3_DB']->SELECTquery ('*','laendervorwahlen', 'lvorwahl='.$country[$zaehler]);

Dann siehst Du was dort für eine Query gebildet wird.

Gruss
Markus

saltletts ·
marksta schrieb

Als erstes war ich erstaunt über deine erste Query. Du lädst alle Adressen, welche auf der Seite sind, welche die gleiche Page-Uid haben, wie die User-Uid des aktuellen Benutzers. Naja, sowas kanns ja geben. 🙂

Das macht (in meinem Fall) durchaus Sinn! Denn es geht um eine Art Historie erstellter Adressen, die zum aktuellen User gehören. Deshalb lese ich alle diese Adressen aus. Das ist schon richtig so.

Und zum restlichen Tipp. Werde ich mir mal anschauen, sobald ich dazu komme ;-)

Danke schonmal....

ÁndreMansfeld ·

Hallo,
hab ich auch gerade hintermir :-)

Ich habe die Query mit einem Join zusammengeführt.
Also hole Daten aus Tabelle A und Tabelle B -> bei der aus Tabelle A ein Wert mit Tabelle B übereinstimmt. Dann wird dir das $res alles relevante ausspucken.

Ich habe das folgendermaßen gemacht, wobei ich hier schnell die gewünschte Funktion erklären möchte, damits dann einfacher wird.
Ich habe 2 Tabellen (fe_user und eine eigene Extension). Nun habe ich die Anforderung... Hole aus der eigenen Extension einen Wert der mit $kunde übereinstimmt. $kunde ist bei mir jetzt der aktuell eingeloggte Kunde (ID).
Wenn es eine Übereinstimmung mit KUNDE gibt, dann zeige alle Daten aus der FE_USER Tabelle. Ich habe diese Funktion gebraucht, weil hier KUNDEN eine USERAUSWAHL speichern können sollen :-). Also Kunde 1 schaut sich gerne USER 2, USER 3, USER 15 u.s.w. an. (Frag nicht warum :-) ). Die Tabelle der eigenen EXTENSION sieht einfach so aus.

uid = id des angelegten Datensatzes
userid = die gespeicherte User ID.
kundenid = die gespeichert Kunden ID.
aktiviert = 0 oder 1 (ist Favorit oder eben nicht)

Wenn jetzt ein eingeloggter Kunde einen USER anschaut, kann er bei mir dann per Formularbuttom sagen, DIESEN USER IN MEINE FAVORITEN SAMMLUNG SPEICHERN
und dann wird ein Datensatz in meiner Extension erzeugt, der ungefähr so aussieht.
KUNDEN ID USER ID
----1------------2------
----1------------3------
----1------------15------

Jetzt möchte ich im FE eine Liste der Favoriten meinem Kunden zeigen, also muß ich die 2 Tabellen ja zusammenführen.
Also schreibe ich folgendes:
Tabelle fe_users wird zu u und Tabelle schaufenster (meine Eigene) wird zu s.
u und s sind Aliase für die Tabellen (geht auch ohne, ist aber viel schreiben)
Wichtig ist bei SELECT steht z.B. u.*,s.* könnte natürlich auch u.uid o.ä. heissen. Wobei hier angegeben wird was das Script auslesen soll (aus beiden Tabellen)

Und in FROM steht dann das u und das s hinter den zwei Tabellen(Leerzeichen dazwischen)die ich ansprechen möchte. Das INNER JOIN verküpft nun u und s mit dem ON auf einem bestimmten FELD (bei mir die uid).
Als letztes gebe ich noch ein paar WHERE Dinge mit :-)

$kunde = $GLOBALS['TSFE']->fe_user->user['uid']; // Aktuelle USER ID des eingeloggten Kunden
$query = "SELECT u.*, s.* FROM fe_users u INNER JOIN schaufenster s ON u.uid = s.userid WHERE s.kundenid = $kunde AND s.aktiviert = 1 AND u.usergroup = 3 AND hidden = 0";
                $res = mysql(TYPO3_db,$query);
		while($row=$GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)){
		......
                }

In die while Schleife kommen jetzt nur noch die Marker zur Ausgabe.
Wobei jetzt aus beiden Tabellen die Daten einfließen :-)
Also z.B.
$markerArray['###VORNAME###']=$row['first_name'];
$markerArray['###NAME###']=$row['last_name'];

Habs mal wieder ausführlicher geschrieben, weil ich selbst ewig suchen mußte und mir in den Suchmaschinen auch nicht so viele (einfache) Beispiele untergekommen waren.
Ich hoffe ich konnte helfen :-)
Andreas

PS: Da fällt mir ein :-)
Wenn du bei den Markern erweiterte Tabellen nimmst (ich habe z.B. die fe_users erweitert) dann mußt du diese Daten mit dem Tabellennamen ansprechen.
$markerArray['###HAARFARBE###']=$row['schaufenster_haarfarbe'];

ÁndreMansfeld ·

Und ich nochmal 😃 .
Ich habe eigentlich selber eine Frage zu diesem Thema gehabt und wollte gerade loslegen.

Folgendes:
In meiner WHERE steht:

WHERE s.kundenid = $kunde AND s.aktiviert = 1 AND u.usergroup = 3 AND hidden = 0";

Es werden alle Bedingungen erfüllt und ich erhalte eine richtige Ausgabe.
Es geht nun um das DELETED!!! #angry#

Wenn ich aber noch -< AND deleted = 0 >- dazuschreibe, geht gar nichts mehr :o .
Auch nicht mit u.deleted = 0 oder s.deleted = 0.

Warum wird denn das DELETED nicht richtig behandelt, denn das HIDDEN geht einwandfrei?

Lieben Gruß
Andreas

digedag ·
ÁndreMansfeld schrieb
WHERE s.kundenid = $kunde AND s.aktiviert = 1 AND u.usergroup = 3 AND hidden = 0";

Warum wird denn das DELETED nicht richtig behandelt, denn das HIDDEN geht einwandfrei?

Du machst einen JOIN auf zwei Tabellen. Die Spalte hidden hast du in der WHERE-Bedingung ohne Tabellen-Alias angegeben. Wenn das funktioniert, dann nur deshalb, weil diese Spalte nur in einer der beiden Tabellen vorhanden ist. (Bei fe_users heißt das Feld disabled.)
Deleted ist garantiert in beiden Spalten vorhanden. Und MySQL kommt dann ins grübeln, weil nicht angegeben ist, von welcher Tabelle die Spalte verwendet werden soll. Da steht dann was von "ambiguous columns" in der Fehlermeldung.

Lösung: Bei Joins die Aliase immer bei allen Spalten angeben.

ÁndreMansfeld ·

Hallo digedag,
Danke für die Antwort.
Ist schon richtig was du sagst, aber ich habs natürlich mit den Aliasen probiert.
Hab ja geschrieben, dass ich
"" -> Auch nicht mit u.deleted = 0 oder s.deleted = 0 <- ""
weitergekommen bin o.O .
Das das Feld bei den fe_users disable heisst, wußte ich nicht, DANKE.

Also laut phpmyAdmin steht in der Tabelle(eigene Extension -> schaufenster) ein "deleted". (Habs ja beim Erstellen im Kickstarter angehackt 🙂 )
Das hidden gibts in beiden Tabellen, da ists wohl, sehr richtig bemerkt, angebracht das Alias zu verwenden. Ich will eigentlich nur ausschließen, dass gelöschte Datensätze aus der fe_users angezeigt werden, nur weil in dieser BEZUGSTABELLE noch die Bedingungen dazu stimmen und der Datensatz deswegen trotzdem angezeigt wird.
Eigentlich wäre eine Typo3 konformere Schreibweise mit enableFields das Richtige, aber das hat garnicht geklappt :o

Ich werde es aber nochmal mit den Aliasen und mit disable probieren!!!

Lieben Gruß
Andreas

saltletts ·
ÁndreMansfeld schrieb

Hallo,
hab ich auch gerade hintermir :-)

Ich habe die Query mit einem Join zusammengeführt.
Also hole Daten aus Tabelle A und Tabelle B -> bei der aus Tabelle A ein Wert mit Tabelle B übereinstimmt. Dann wird dir das $res alles relevante ausspucken.

FETTE Antwort, und ich dank dir für deine "ausführliche" Beschreibung. Da kann man echt was mit anfangen 😃

Ich denke ich hab insgesamt das was ich haben wollte. Danke an alle.

digedag ·
ÁndreMansfeld schrieb

Hab ja geschrieben, dass ich
"" -> Auch nicht mit u.deleted = 0 oder s.deleted = 0 <- ""
weitergekommen bin o.O .

Das hab ich doch glatt überlesen... :o
Die Aliase musst du aber unbedingt bei WHERE angeben. Wenn es dann noch nicht klappt, dann schau mal nach, was du bei WHAT angibst. Auch da müssen die Felder eindeutig sein. Am besten probierst du solche problematischen Statements immer direkt im phpMyAdmin aus. Dann siehst du auch immer gleich die Fehlermeldung.

Eigentlich wäre eine Typo3 konformere Schreibweise mit enableFields das Richtige, aber das hat garnicht geklappt :o

Die Funktion unterstützt keine eigenen Aliase. Da werden immer die Tabellennamen als Alias verwendet. In deinem Fall ist das übrigens kein Problem. Du musst nicht s und u verwenden. Du kannst auch den Namen der Tabelle nehmen.

ÁndreMansfeld ·

Danke für die Antwort.
Mittlerweile läuft es auf dem langen Schreibweg :-)
Ist jetzt eine sehr lange QUERY ....

Die Aliase habe ich halt genommen, weil meine letztlich laufenden Tabellen so schreibintensiv sind ;-)

Das die enableFields nicht mit Aliasen gehen, nehme ich hiermit zur Kenntnis ;-).
Hat mich ja nur einen Tag gekostet #angry#

Aber ich rege hiermit mal eine BLACKLIST an,

Die nennen wir dann:
TYPO3 für GANZ GANZ DUMMIES :p

Danke nochmal...bis dann ...
Andreas