pozik
24.04.2013, 18:40:07
Mam tabelę pracownicy(jest to jedyna tabela w bazie), w której mam następujące kolumny: imie, nazwisko, wyplata
Potrzebuje zrobić zapytanie, które wypisze unikalne (imię i nazwisko) i dla tych unikalnych danych tylko najwyższą wypłata.
Ma ktoś pomysł jak to zrobić?
Próbowałem w ten sposób: SELECT DISTINCT imie, naziwsko FROM pracownicy
Nie wiem jak dołączyć do tego najwyższą wypłatę.
ssstrz
24.04.2013, 18:56:25
SELECT DISTINCT imie, nazwisko FROM pracownicy ORDER BY wyplata
mortus
24.04.2013, 19:21:15
Przy takiej budowie tabeli, jaką opisałeś (swoją drogą całkowicie niepoprawną) powinno zadziałać to
SELECT `p`.`imie`, `p`.`nazwisko`, MAX(`p`.`wyplata`) `najwieksza_wyplata` FROM `pracownicy` `p` GROUP BY `p`.`imie`, `p`.`nazwisko`
Michasko
24.04.2013, 19:29:25
WHERE wyplata = max(wyplata)
pozik
24.04.2013, 19:53:57
Cytat(mortus @ 24.04.2013, 20:21:15 )

Przy takiej budowie tabeli, jaką opisałeś (swoją drogą całkowicie niepoprawną) powinno zadziałać to
SELECT `p`.`imie`, `p`.`nazwisko`, MAX(`p`.`wyplata`) `najwieksza_wyplata` FROM `pracownicy` `p` GROUP BY `p`.`imie`, `p`.`nazwisko`
Zadziałało, dzięki! Dlaczego niepoprawną?
Mam jeszcze jedno pytanie. Teraz chciałbym zliczyć najwyższe wypłaty większe od $getwyplata. Zrobiłem zapytanie:
$query = "SELECT imie, nazwisko, MAX(wyplata) AS 'maxwyplata' FROM pracownicy GROUP BY imie, nazwisko WHERE maxwyplata > $getwyplata";
$result = mysql_query($query);
... i dalej nie wiem...
Jest możliwość wrzucenia jakiegoś globalnego COUNT() tutaj?
matiit
24.04.2013, 20:17:04
Zamiast WHERE daj HAVING
pozik
24.04.2013, 20:27:36
Pomogłeś! Dziękuję!
Zrobiłem coś takiego:
(...)
$query = "SELECT imie, nazwisko, MAX(wyplata) AS 'maxwyplata' FROM pracownicy GROUP BY imie, nazwisko HAVING maxwyplata > $getwyplata";
(...)
matiit
24.04.2013, 20:48:57
Jest spoko, tylko pamiętaj o SQL injection
pozik
24.04.2013, 21:13:28
Zabezpieczyłem w taki sposób:
$getwyplata = str_replace("<", "", $getwyplata);
$getwyplata = str_replace(">", "", $getwyplata);
$getwyplata = str_replace("!", "", $getwyplata);
$getwyplata = str_replace("/", "", $getwyplata);
$getwyplata = str_replace("\", "", $getwyplata);
Wystarczy?
matiit
24.04.2013, 21:23:37
Nie, bo co jak $getwyplata będzie np. "10; DROP TABLE pracownicy;" ?
Ale fajnie, że kombinujesz i próbujesz.
Polecam Ci po prostu poczytać o SQL injection, jest tego masa na necie.
Ale idziesz w dobrym kierunku, gratuluję
mmmmmmm
24.04.2013, 21:33:15
Wystarczy proste intval()... I o SQL-injection możesz zapomnieć.
pozik
24.04.2013, 21:37:20
Poszukam i poczytam dzięki matiit

Dzieki mmmmmmm za pokazanie jak zabezpieczyć przekazywanie wartości

Teraz jeszcze poszukam jak skutecznie zabezpieczyć stringa
matiit
24.04.2013, 21:40:20
Kolega wyżej ma rację. Wtrące jeszcze tylko swoje 0.03PLN - lepiej użyć (int) $zmienna niż intval($zmienna) z powodów optymalizacyjnych.
Tutaj "benchmark"
http://hakre.wordpress.com/2010/05/13/php-casting-vs-intval/
pozik
24.04.2013, 22:54:49
Nigdy nie zdawałem sobie sprawy z tego, że włamanie się do bazy może być tak łatwe. Udało mi się przeprowadzić atak na mojej bazie. Teraz już zabezpieczyłem trochę. Pomogliście mi. Co do zabezpieczania stringów, to znalazłem: $imie = mysql_escape_string($imie);
pmir13
24.04.2013, 23:14:33
Skoro już znalazłeś taką funkcję to mam nadzieję, że przeczytałeś do niej manual, gdzie w wielkim czerwonym oknie na samej górze napisane jest, że już w tej chwili wszystkie funkcje z mysql_ są przestarzałe, a w przyszłych wersjach będą w ogóle usunięte.
W zasadzie nie rozumiem dlaczego dyskutujecie na temat jak zabezpieczyć kod typu mysql_ zamiast dyskutować o tym że w ogóle nie należy go stosować. Serio, PDO nie jest takie straszne jak się wydaje, a parametryzowane wywołania zupełnie eliminują problem SQL injection. Wciąż trzeba uważać na XSS jeśli wypluwamy na stronę jakikolwiek html z bazy, ale to i tak duży postęp w stosunku do tego na co trzeba uważać z mysql_.
pozik
24.04.2013, 23:23:39
Nie zwróciłem uwagi na taką informację. Wychodzi na to, że nadal muszę szukać rozwiązania...
pmir13
24.04.2013, 23:36:47
$dbh = new PDO( ... );
...
$query = "SELECT imie, nazwisko, MAX(wyplata) AS 'maxwyplata' FROM pracownicy GROUP BY imie, nazwisko HAVING maxwyplata > :getwyplata";
$stmt = $dbh->prepare( $query );
$stmt->bindParam( ':getwyplata', $getwyplata, PDO::PARAM_INT );
$stmt->execute();
Szymciosek
24.04.2013, 23:50:24
Cytat(pmir13 @ 25.04.2013, 00:14:33 )

Skoro już znalazłeś taką funkcję to mam nadzieję, że przeczytałeś do niej manual, gdzie w wielkim czerwonym oknie na samej górze napisane jest, że już w tej chwili wszystkie funkcje z mysql_ są przestarzałe, a w przyszłych wersjach będą w ogóle usunięte.
W zasadzie nie rozumiem dlaczego dyskutujecie na temat jak zabezpieczyć kod typu mysql_ zamiast dyskutować o tym że w ogóle nie należy go stosować. Serio, PDO nie jest takie straszne jak się wydaje, a parametryzowane wywołania zupełnie eliminują problem SQL injection. Wciąż trzeba uważać na XSS jeśli wypluwamy na stronę jakikolwiek html z bazy, ale to i tak duży postęp w stosunku do tego na co trzeba uważać z mysql_.
Możesz coś więcej powiedzieć o XSS? Jak to ma się do trzymania w bazie kodu html i wyświetlania go np. przy korzystania z klasy View, która pobiera i wyświetla html z bazy?
pmir13
25.04.2013, 00:05:02
W XSS w bardzo dużym skrócie chodzi o to, że jeśli użytkownik ma możliwość wprowadzenia do bazy gdziekolwiek jakiegokolwiek tekstu, z którego potem będzie składany html, to może próbować wstawić coś, co uruchomi javascript, którego źródło może być gdzieś na zewnętrznym serwerze. Przykłady tego, co można próbować wstawić do bazy można znaleźć tutaj:
https://www.owasp.org/index.php/XSS_Filter_...ion_Cheat_Sheet.
Jeśli chodzi o widoki to wszystko zależy od tego jak są napisane, każdy przypadek jest inny, na pewno bezpieczny jest tylko taki html z bazy, na który użytkownik odwiedzający stronę nie ma wpływu.
mmmmmmm
25.04.2013, 07:23:35
Sorry, ale większego szajsu niż PDO to dawno nie spotkałem...
Programuję długo (ponad 20 lat) w wielu językach. W PHP jakieś 5-6 lat. Zawsze używałem mysql_ jako najszybsze. Ostatnio próbowałem PDO. Takich problemów, jak z PDO to dawno nie miałem... Każda następna będzie na pewno z użyciem mysqli_
Aby nie być gołosłownym:
1. UPDATE `tabela` SET `pole='wartość' WHERE `id`=1
Brak błędu - zarówno w PDOException, jak i errorInfo().
2. Nie zgłasza błędów w momencie nie dodania rekordów z powodu np. złego triggera.
3. rowCount() nie daje wyników dla SELECT (to akurat jest opisane w dokumentacji) - porażka.
matiit
25.04.2013, 08:58:15
pmir13
Wg mnie i tak warto znać podstawy zabezpieczeń, a i trochę "historii" jak to było parę lat temu też nikomu nie zaszkodzi.
Czy się przydać może to w praktyce? Oczywiście. Miałem ostatnio klienta, który miał serwis na serwerze bez możliwości włączenia PDO czy mysqli, miałem dorobić trochę funkcjonalności i trzeba było się w tym babrać, cóż poradzić.
A przy okazji dopisują swój kod nie mogłem pozwolić na to, aby był podatny na ataki - więc musiałem wiedzieć jakie są podstawowe zagrożenia przy używaniu mysql_*
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.