INNER JOIN = wyciąganie danych

0

Witam,

Mam taki problem. Musze przerobić swoje zapytania złożone na formę z INNER JOIN (poniekąd przy większej liczbie rekordów serwer się zawiesi). Jedno z zapytań działa ok, zwraca wszystkie rekordy:

"SELECT b.nazwa_branzy, u.login, o.tresc, i.rodzaj_umowy, l.lokalizacja FROM ogloszenia AS o 
				  JOIN users u ON u.id_usera = o.id_usera 
				  JOIN branza b ON b.id_branzy = o.id_branzy 
				  JOIN umowa i ON i.id_umowy = o.id_umowy 
				  JOIN lokalizacja l ON l.id_lok = o.id_lok"
 

Gorzej jest jak próbuję wyciągnąć już coś GET. Średnio mi to wychodzi. Zrobiłem coś takiego:

 
"SELECT b.nazwa_branzy, u.login, o.tresc, i.rodzaj_umowy, l.lokalizacja FROM ogloszenia AS o, branza AS b 
				  JOIN users u ON u.id_usera = o.id_usera 
				  JOIN branza b ON b.nazwa_branzy = '{$_GET['nazwa']}' 
				  JOIN umowa i ON i.id_umowy = o.id_umowy 
				  JOIN lokalizacja l ON l.id_lok = o.id_lok"

I niestety również zwraca mi wszystko. Jak powinno wyglądać takie zapytanie?

0

Powinieneś dodać warunek WHERE a nie kombinować w warunku złączenia złączeniem. JOIN służy do łączenia tabel - parowania rekordów z dwóch różnych tabel. Możesz wrzucic ten swój warunek w JOINa ale wtedy JOIN branza b ON JOIN branza b ON b.id_branzy = o.id_branzy and b.nazwa_branzy = '{$_GET['nazwa']}'

0

Taki zapis także generuje wyświetlanie wszystkich rekordów:

 
"SELECT b.nazwa_branzy, u.login, o.tresc, i.rodzaj_umowy, l.lokalizacja FROM ogloszenia AS o, branza AS b 
				  JOIN users u ON u.id_usera = o.id_usera 
				  JOIN branza b ON b.id_branzy = o.id_branzy 
				  JOIN umowa i ON i.id_umowy = o.id_umowy 
				  JOIN lokalizacja l ON l.id_lok = o.id_lok 
				  WHERE b.nazwa_branzy = '{$_GET['nazwa']}'"
0

Właśnie sprawdziłem w PhpMyAdmin. Takie zapytanie w PMA działa:

 
SELECT b.nazwa_branzy, u.login, o.tresc, i.rodzaj_umowy, l.lokalizacja FROM ogloszenia AS o JOIN users u ON u.id_usera = o.id_usera JOIN branza b ON b.id_branzy = o.id_branzy JOIN umowa i ON i.id_umowy = o.id_umowy JOIN lokalizacja l ON l.id_lok = o.id_lok WHERE b.nazwa_branzy = "elektromechanik"

A w skrypcie już nie:

if(!empty($_GET['nazwa'] =="elektromechanik" || $_GET['nazwa'] =="murarz" || $_GET['nazwa'] =="slusarz" || $_GET['nazwa'] =="kowal") && $_GET['umowa'] == "---" && $_GET['lokalizacja'] == "---")
		{
			try
			   {
				  $pdo = new PDO($pol, $user, $pass);
				  $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
				  if(isset($_GET['nazwa']))
				  {
				  $stmt = $pdo->query("SELECT b.nazwa_branzy, u.login, o.tresc, i.rodzaj_umowy, l.lokalizacja FROM ogloszenia AS o 
				  JOIN users u ON u.id_usera = o.id_usera 
				  JOIN branza b ON b.id_branzy = o.id_branzy 
				  JOIN umowa i ON i.id_umowy = o.id_umowy 
				  JOIN lokalizacja l ON l.id_lok = o.id_lok 
				  WHERE b.nazwa_branzy = '{$_GET['nazwa']}'");
				  echo '<ul>';
				  foreach($stmt as $row)
				  {
					  echo '<li>'.$row['nazwa_branzy'].': '.$row['rodzaj_umowy'].': '.$row['login'].': '.$row['tresc'].': '.$row['lokalizacja'].'</li>';
				  }
				  $stmt->closeCursor();
				  echo '</ul>';
				  //print_r($_GET);
			   }
			   }
			   catch(PDOException $e)
			   {
				  echo 'Połączenie nie mogło zostać utworzone: ' . $e->getMessage();
			   }
		}	
 

Select:

 
<select name="nazwa" value="nazwa">
		<option><?php if(isset($_GET['nazwa'])) {echo ($_GET['nazwa']);} else {echo "---";} ?></option>
		<option>---</option>
		<option>elektromechanik</option>
		<option>murarz</option>
		<option>slusarz</option>
		<option>kowal</option>
	</select>

Gdzie może być błąd?

0
                  $stmt = $pdo->query("SELECT b.nazwa_branzy, u.login, o.tresc, i.rodzaj_umowy, l.lokalizacja FROM ogloszenia AS o 
                  JOIN users u ON u.id_usera = o.id_usera 
                  JOIN branza b ON b.id_branzy = o.id_branzy 
                  JOIN umowa i ON i.id_umowy = o.id_umowy 
                  JOIN lokalizacja l ON l.id_lok = o.id_lok 
                  WHERE b.nazwa_branzy = '{$_GET['nazwa']}'");

Ok, a teraz wyobraź sobie że przekazuje na stronie parametr GET nazwa o wartości:

cośtam' union select user, password from tabela_z_haslami where '1'='1

Albo coś równie ciekawego...
Lekcja na dziś: SQL Injection i Prepared Statements

Sprawdź sobie w tym skrypcie jaką ma wartość ta zmienna przed wykonaniem zapytania.

0

SQL Injection jest załatwione na poziomie instrukcji warunkowej:

 
if($_GET['nazwa'] =="elektromechanik" || $_GET['nazwa'] =="murarz" || $_GET['nazwa'] =="slusarz" || $_GET['nazwa'] =="kowal" && $_GET['umowa'] == "---" && $_GET['lokalizacja'] == "---")
1

Nie znam PHP ale patrząc na twoje zapytanie to przekazujesz do serwera baz danych warunek WHERE postaci : '{$_GET['nazwa']}' czyli serwer szuka ci wszytskich rekordów dla których nazwa branży jest równa dokładnie wartości '{$_GET['nazwa']}' a nie wartości która kryje się pod tym get (np. elektromechanik). Musisz złożyć ten string.

Co do twojego zabezpieczenia - słabe to jest że dodanie nowej branży powoduje konieczność podmiany samej aplikacji.

0

W2K masz absolutna rację. Właśnie to naprawiam i przy okazji zaoszczędziłem dużo miejsca.

1 użytkowników online, w tym zalogowanych: 0, gości: 1