PDA

Zobacz pełną wersję : phpMyAdmin



simon111
07-05-07, 21:12
Witam
Tworząc sobie bazę danych użyłem narządzia phpMyAdmin dołączonego do programu KrasnalServ. Czy istnieje jakaś komenda dzięki, której mógłbym operaować na datach?
Bo jak wpisuję w phpMyAdmin zapytanie SQL:


SELECT MONTHS_BETWEEN(SYSDATE, data)
FROM przeglad_naprawa;

To mi wyświetla błąd. Nie mogę nawet wywołać prostej funkcji typu:


SELECT SYSDATE
FROM DUAL;

Bo mi mówi że nie ma takiej tabeli (jakbym nie wiedział :? ). Bardzo proszę o pomoc w tej kwestii, bo nie wiem co mam teraz zrobić. Z góry dziękuję za pomoc, pozdrawiam, narka. Simon

doderic
08-05-07, 00:08
SELECT SYSDATE() FROM DUAL;
U mnie działa... z nawiasami ;-)


Za to nie mam funkcji MONTHS_BETWEEN :-?

simon111
08-05-07, 09:35
A jakiego narzędzia używasz bo u mnie to nawet z nawiasami nie działa :(

doderic
08-05-07, 10:08
Ja to hardcorowo: "MySQL Command Line Client".
(z głupich pytań: mówmy o bazie MySQL? 8) )

Właśnie znalazłem opis bug-a w MySQL:
http://bugs.mysql.com/bug.php?id=15101
Wynika z niego, że funkcja sysdate() została jakoś pozmieniana w MySQL 5.0.17. Alternatywą jest używanie funkcji now().

Jakiej wersji MySQL używasz? Być może musiałbym spróbować tej samej.
Ja mam "server version: 5.0.37-community-nt MySQL Community Edition (GPL)".

simon111
08-05-07, 10:36
MySQL 3.23.58 - oto wersja, której aktualnie używam (oferowana przez krasnala :p)
Właśnie też udało mi się dokopać do tych informacji, masz rację funkcja

Select now()
pokazuje nie tylko date, ale też aktualny czas. Mi wystarczy tylko data co można uzyskać dzięki funkcji:


Select curdate();

Ale nie mogę wykombinować jak odjąć dwie daty od siebie, ażeby uzyskać ilość dni (miesięcy), jak między nimi upłynęła. Zapytanie np:


Select (2005-03-25)-(2005-06-11);

zwraca błędny wynik, że nie wspomnę już o:


Select (curdate())-(2005-06-11);

Czy masz może jakiś pomysł na operacje na datach? Próbowałed już z adddate, datediff, ale nie działa :(.

doderic
08-05-07, 11:29
Zapytanie np:

Select (2005-03-25)-(2005-06-11);
zwraca bdny wynik (...)
(2005-03-25)-(2005-06-11) = 1977 - 1988 = -11 <- taki powinien by wynik ;-)

Jak by mia wersj MySQL 4.1.1 lub nowsz, to sprawa prosta:

Select datediff(20050325,20050611);
Select datediff('2005-03-25', '2005-06-11');
Oba zwracaj -78.

Natomiast w Twojej wersji powinno zadziaa:

Select to_days('2005-03-25') - to_days('2005-06-11');
radz zajrze do http://dev.mysql.com/doc/refman/4.1/en/date-and-time-functions.html#function_to-days bo nie zawsze mona tej funkcji uywa.

Konwersja na "miesice", np.:

Select truncate( (to_days('2005-03-25')-to_days('2005-06-11'))/30, 0);

8)

simon111
08-05-07, 14:54
Dzięki wielkie za odpowiedź, właśnie o to mi chodziło i teraz wszystko wymiata mi tak jak właśnie tego chciałem :poklony:
Myślę, że temat można uważać za zamknięty, chyba, że jeszcze ktoś chce coś dopisać ;p
Pozdrawiam i jeszcze raz dziękuję, narka.

RRybak
08-05-07, 15:39
To ja sobie chcę dodać: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

Zwróć szczególną uwagę na wyrażenia typu timediff, day, interval, hour itp... ;)

doderic
08-05-07, 16:59
To ja sobie chcę dodać: http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html

Zwróć szczególną uwagę na wyrażenia typu timediff, day, interval, hour itp... ;)
RRybak, podałeś niestety linka do notatek dla wersji MySQL 5.x. Simon111 używa MySQL 3.23.58, a w niej jeszcze nie ma timediff, day, etc. Te funkcje są dostępne dopiero od wersji v4.1.1 (jak można zauważyć na stronie, którą podałeś).

simon111
08-05-07, 20:20
A macie może pomysł dlaczego nie chce wykonać mi tego pytania?:


SELECT lpp_n, id_drukarki, data
FROM przeglad_naprawa
WHERE lpp_n = ANY (SELECT lpp_n
FROM przeglad_naprawa
GROUP BY id_drukarki)

Jak zadaje je oddzielnie to wychodzi, ale gdy przyrównuje z ANY to tak jakby nie rozumiał tego polecenia.

doderic
08-05-07, 22:23
1. Czy możesz upgrade-ować MySQL do nowszej wersji? Ewentualnie zmienić serwer na inny, z nowszą wersją MySQL?

2. Z tego co widzę, to próbujesz robić rzeczy używając funkcji/składni, których u Ciebie jeszcze nie ma:
http://dev.mysql.com/doc/refman/4.1/en/rewriting-subqueries.html
Tak więc jeśli już, to raczej spróbuj użyć IN zamiast =ANY:

SELECT lpp_n, id_drukarki, data FROM przeglad_naprawa
WHERE lpp_n IN (SELECT lpp_n FROM przeglad_naprawa GROUP BY id_drukarki)
lub wręcz użyj JOIN:

SELECT dane.lpp_n, dane.id_drukarki, dane.data FROM przeglad_naprawa AS dane
INNER JOIN
(SELECT lpp_n FROM przeglad_naprawa GROUP BY id_drukarki) AS lista
ON dane.lpp_n = lista.lpp_n
* nie testowałem tych zapytań na wersji 3.x, a na 5.x nawet oryginalne działa - tak więc pisałem "na sucho"

Niezbyt rozumiem, co to zapytanie ma dokładnie robić, być może istnieje lepszy sposób na osiągnięcie celu?
No i jak tak dalej pójdzie, to chyba poproszę Cię o podesłanie bazy, najlepiej z jakimiś danymi testowymi od razu ;-)

RRybak
09-05-07, 08:12
Rybak, podałeś niestety linka do notatek dla wersji MySQL 5.x. Simon111 używa MySQL 3.23.58
A, tego to ja w wątku nie widziałem. Chyba, że ten cały Krasnal ma takie cuda. Upgraduj chłopie mySQL do najnowszej wersji i się nie męcz. Bezpieczniejszy też będziesz ;)

Co do zapytania, to nie będę się kłócił czemu coś pod 3.x nie działa, ale przychodzi mi na myśl to, że każde podzapytanie powinno mieć własny alias - tak jak napisał doderic - "AS LISTA"..

simon111
09-05-07, 09:08
Udao mi si wykona to samo zapytanie ale nie uywajc ANY (swoj drog IN te nie dziaao, ale teraz z JOIN'em nie prbowaem - chciaem ju go kiedy uy w innym przypadku to go nie zrozumia). Wracajc do tematu uyem klauzuli MIN() w SLECT wszystko na kocu grupujc wzgldem id_drukarki. Wtedy zrozumia :).

Tak jak mwi RRybak bd musia upgredowa sobie tego mySQL'a jak tak dalej pjdzie, ale pki mona posugiwa si starsz wersj to chyba lepiej jej uywa (nie wiem dokadnie jak to dziaa w praktyce, ale kwestia przesyania strony WWW wraz z baz na serwer globalny zasuguje ju na nowy wtek, ktry nie zaprzeczam, e porusz, ale musz skoczy stronk u siebie :) )

PS. A zapytanie ma za zadanie wywietla przegldy drukarek u ktrych min ju rok od przegldu.
1 tabela: drukarka (atrybuty: nazwa, model, id_drukarki(PK), nr_seryjny, miejsce_instalacji, miejscowosc, ulica, nip(FK), lpp_n(FK))
2 tabela: przeglad_naprawa(rodzaj, lpp_n(PK), id_drukarki(FK), data)

RRybak
09-05-07, 09:38
ale póki można posługiwać się starszą wersją to chyba lepiej jej używać (nie wiem dokładnie jak to działa w praktyce, ale kwestia przesyłania strony WWW wraz z bazą na serwer globalny
I tu właśnie możesz mieć problem. Po pierwsze większość firm hostingowych udostępnia już teraz tandem w postaci MySQL 5 + PHP5. Jeśli korzystasz ze starszych wersji, możesz się niemile zdziwić przy przenoszeniu - właśnie przez niedziałające funkcje, działające inaczej lub już nieistniejące.
Dodatkową kwestią jest bezpieczeństwo i stabilność bazy (a przez to całego Twojego serwisu internetowego). Być może założysz nowy wątek, ale już teraz radziłbym Ci się przestawić. Z doświadczenia wiem, jak niepozorny skok między wersjami 4 na 5 może uprzykrzyć tygodnie życia. Powtórzę - upgraduj póki czas :)

doderic
09-05-07, 10:32
Zacznę od końca:


1 tabela: drukarka (atrybuty: nazwa, model, id_drukarki(PK), nr_seryjny, miejsce_instalacji, miejscowosc, ulica, nip(FK), lpp_n(FK))
2 tabela: przeglad_naprawa(rodzaj, lpp_n(PK), id_drukarki(FK), data)
Z tego co widzę, masz tutaj problem ze schematem bazy danych: tabela pierwsza ma klucz obcy do tabeli drugiej, a potem druga do pierwszej. Tak się nie robi! Wg. mnie niepotrzebne jest tutaj drukarka( lpp_n(FK) ).


PS. A zapytanie ma za zadanie wyświetlać przeglądy drukarek u których minął już rok od przeglądu.

Podstawowe zapytanie, ja bym napisał tak:

SELECT DISTINCT id_drukarki FROM przeglad_naprawa WHERE to_days(curdate())-to_days(data) > 365

Potem można do tego dodać więcej szczegółowych danych, np. o drukarce, stosując INNER JOIN bądź IN.



(...) ale póki można posługiwać się starszą wersją to chyba lepiej jej używać (...) kwestia przesyłania strony WWW wraz z bazą na serwer globalny zasługuje już na nowy wątek, który nie zaprzeczam, że poruszę, ale muszę skończyć stronkę u siebie
Czy to znaczy, że nie masz wybranego żadnego miejsca docelowego? Ups... będziesz miał sporo problemów. O wiele lepiej było by wybrać hosting, dowiedzieć się jakich dokładnie wersji używają, i na dokładnie takich tworzyć swoje dzieło u siebie.
Posłuchaj chociaż jednego z nas (RRybaka w poprzednim poście lub mnie). 8)

simon111
09-05-07, 19:14
Z tego co widz, masz tutaj problem ze schematem bazy danych: tabela pierwsza ma klucz obcy do tabeli drugiej, a potem druga do pierwszej. Tak si nie robi! Wg. mnie niepotrzebne jest tutaj drukarka( lpp_n(FK) ).

Susznie pomyliem si przy pisaniu. Oto tabela drukarka:


CREATE TABLE `drukarka` (
`nazwa` VARCHAR (10) NOT NULL,
`model` VARCHAR (15) NOT NULL,
`nr_seryjny` VARCHAR (20) NOT NULL,
`rodzaj` VARCHAR (15) NULL,
`id_drukarki` VARCHAR (15) NOT NULL PRIMARY KEY,
`zlacze` VARCHAR (20) NULL,
`status` VARCHAR (10) NULL,
`miejsce_instalacji` VARCHAR (10) NOT NULL,
`miejscowosc` VARCHAR (20) NOT NULL,
`ulica` VARCHAR (20) NULL,
`nip` NUMERIC ( 10,0 ) NOT NULL,
FOREIGN KEY (`nip`) REFERENCES firma(`nip`)
) Type=BerkeleyDB
;

A to tabela przegldw i napraw:


CREATE TABLE `przeglad_naprawa` (
`rodzaj` VARCHAR (10) NOT NULL,
`data` DATE NOT NULL,
`lpp_n` NUMERIC (10,0) NOT NULL PRIMARY KEY,
`id_drukarki` VARCHAR (15) NOT NULL,
FOREIGN KEY (`id_drukarki`) REFERENCES drukarka(`id_drukarki`)
) Type=BerkeleyDB
;

Jeeli popeniem gdzie bd to prosz zwrdzcie mi uwag, ale myl e s one poprawnie zbudowane.

A jeeli chodzi o:


Czy to znaczy, e nie masz wybranego adnego miejsca docelowego?

to zastanawiam si powanie, czy nie postawi tego na kompie swoim i jego zrobi sobie "serwerem globalnym" ;p
Przynajmniej kwesti poprawnoci dziaania, interpreterw, a nawet upgrade'owania miabym w zasadzie z gowy. Co wy na to?

doderic
10-05-07, 09:08
Jeeli popeniem gdzie bd to prosz zwrdzcie mi uwag, ale myl e s one poprawnie zbudowane.

No, teraz te 2 tabelki s OK :tak_trzymaj: Oczywicie moesz pomyle o "wystandaryzowaniu" takich rzeczy, jak np. rodzaj drukarki czy zcze drukarki poprzez podczenie ich do dodatkowych tabel sownikowych...


(...) zastanawiam si powanie, czy nie postawi tego na kompie swoim i jego zrobi sobie "serwerem globalnym" ;p
Przynajmniej kwesti poprawnoci dziaania, interpreterw, a nawet upgrade'owania miabym w zasadzie z gowy. Co wy na to?
Na pewno nie bdziesz musia si przejmowa zgodnoci, bo sam moesz decydowa, co jest dla Ciebie standardem. Natomiast bdziesz mia za to wszystkie problemy zwizane z utrzymaniem takiego serwera: upgrady, wyczenia prdu, ISP nawali, kwestie bezpieczestwa, dostpu, zarzdzania uytkownikami, wydajno...
Oczywicie nie wiem, czy to jest aplikacja wewntrzna dla firmy, czy klienci maj mie dostp do caoci/czci informacji poprzez sie, itp. wic ciko mi tu wypowiada si, co bdzie najlepsze w Twojej sytuacji.

simon111
10-05-07, 13:10
Oczywiście możesz pomyśleć o "wystandaryzowaniu" takich rzeczy, jak np. rodzaj drukarki czy złącze drukarki

Dokładnie tak też zrobiłem, a ściślej biorąc w formularzach dałem formułę "select name" i zadałem odpowiednie wartości do wyboru :).

A aplikacja ma działać dla jednej firmy, w zasadzie będzie z niego korzystać ściśle określona, grupa osób i chodzi o to żeby mogła mieć dostęp do strony z każdego miejsca - ot takie jest jej przeznaczenie.

doderic
10-05-07, 21:50
(...) będzie z niego korzystać ściśle określona, grupa osób i chodzi o to żeby mogła mieć dostęp do strony z każdego miejsca(...)
Miałem cichą nadzieję, że powiesz, iż aplikacja będzie tylko używana z sieci lokalnej - wtedy sprawa byłaby prostsza: chowasz wszystko za firewallem ;).
No ale w Twoim przypadku, to już jest trochę bardziej skomplikowane. Musisz zapewnić dostęp poprzez internet, zarazem ograniczając go tylko do garstki "wtajemniczonych" 8-). Tak na szybko przychodzi mi do głowy: stronę zabezpieczasz hasłem na poziomie serwera www i zezwalasz tylko na połączenia do MySQLa pochodzące z serwera www / sieci lokalnej (to tak, żeby nikt z zewnątrz nie mógł się połączyć tam bezpośrednio).
No i oczywiście takie rzeczy robi się raczej na Linuxie... ;)

ps. Jeśli chciałbyś, żebym rzucił okiem na pozostałe tabelki...

simon111
11-05-07, 10:37
ps. Jeli chciaby, ebym rzuci okiem na pozostae tabelki...

Chtnie podrzuce te tabelki, eby mg na nie rzuci okiem, ale to wieczorem, bo niestety nie mam ich przy sobie :).

A czy mgby rzuci okiem na takie zapytanie:


<?php
// odbieram dane z formularza

$id_drukarki = $_POST['id_drukarki'];
if($id_drukarki) {

//cze si z baz

$link = mysql_connect("localhost", "root", "krasnal")
or die("Could not connect");

//wybieram rodzaj bazy
mysql_select_db("serfis")
or die("Could not select database");

$query = "SELECT nazwa FROM wykonana_czynnosc WHERE id_drukarki='$id_drukarki'";
$result = mysql_query($query)
or die("Query failed");

while ($row = mysql_fetch_array($result)) {
echo "<table border width='120'><TR><TD width='120'>" . $row["nazwa"] ."</TD> </TR>\n</table>";

}
mysql_free_result($result);
mysql_close($link);
}
?>

W zapytaniu tym odbieram dan z formularza i chce zeby wywietlio mi wykonane czynnoci wzgldem danej drukarki (zapytanie SQL jest ok, bo w phpMyAdmin wymiata). A nie mog tutaj doszuka si jakiego bdu...:sad:

doderic
11-05-07, 23:53
Sprawdzie, czy zmienna jest przekazywana prawidowo przez 'post'?
Nie opisae, jaki dokadnie bd otrzymujesz - zakadam, e dane si nie wywietlaj?

Twj formularz powinien mie nagwek w rodzaju:

<form action="czynnosci.php" method="post">
*czynnosci.php to kod, ktry zaprezentowae w poprzednim pocie.

Nie widz nic, co mogo by si psu w Twoim kodzie, wic ja bym doda:

$id_drukarki = $_POST['id_drukarki'];
if($id_drukarki) {
echo "Szukam dla drukarki: " . $id_drukarki;
(...)
mysql_free_result($result);
mysql_close($link);
} else { echo "Nie znaleziono drukarki o ID: " . $id_drukarki; }

i sprawdzi w ten sposb, ktra cz kodu jest dokadnie wykonywana.

simon111
13-05-07, 07:29
Poprawiem kod i teraz wszystko chodzi mi adnie:



<html>
<head></head>
<body>
<?php
$id_drukarki = $_POST['id_drukarki'];
if($id_drukarki) {

$link = mysql_connect("localhost", "root", "krasnal")
or die("Could not connect");

mysql_select_db("serfis")
or die("Could not select database");


$zapytanie = mysql_query("SELECT w.nazwa, w.ilosc, w.lpp_n, p.id_drukarki, p.data FROM
wykonana_czynnosc as w, przeglad_naprawa as p WHERE w.lpp_n=p.lpp_n and p.id_drukarki='$id_drukarki'");

while ($row = mysql_fetch_array($zapytanie))
{
echo "<center><table border width='900'><TR><TD width='180' >" . $row["nazwa"] ."</TD>
<TD width='180' align='center'>" . $row["ilosc"] ."</TD>
<TD width='180' align='center'>" . $row["lpp_n"] ."</TD>
<TD width='180' align='center'>" . $row["id_drukarki"] ."</TD>
<TD width='180' align='center'>" . $row["data"] ."</TD>
</TR>\n</table></center>";
}
}

mysql_free_result($zapytanie);
mysql_close($link);
?>

</body>
</html>

Dziki za pomoc doderic :)

doderic
13-05-07, 11:03
Poprawiem kod i teraz wszystko chodzi mi adnie
Patrz, przygldam si, analizuj i nie widz!
Nie widz, co takiego zmienie, e zaczo dziaa? :hmmm:
Czyby jednak poprzedni SELECT:

$query = "SELECT nazwa FROM wykonana_czynnosc WHERE id_drukarki='$id_drukarki'";
nie zwraca danych?

Czy moe to chodzi o przeniesienie

mysql_free_result($result);
mysql_close($link);

poza blok IF?
IMHO: to przeniesienie nie jest prawidowe, bo ten kawaek wykonywany jest zawsze, nawet jeli nie uda si uzyska poczenia z baz = nie ma poczenia do zamknicia, zwolnienia zasobw z wyniku zapytania.