Alle Jahre wieder: 31.12.2007 in KW 01/2008

Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 12:31:03 von Erik Hastens

Hallo,

ich betreibe eine Statistik Webseite, auf der erreichte (Lauf-)Zeiten
eingegeben und ausgewertet werden können.

Bei allen Anzeigen der Art Läufe pro Kalenderwoche habe ich, wie auch schon
2006, Probleme mit dem Jahreswechsel. Ich übergebe derzeit Kalenderwoche und
Jahr mit

WHERE ... AND DATE_FORMAT(date,'%v') = '$w' AND DATE_FORMAT(date,'%Y') =
'$_GET[year]'

mit PHP Variablen, wie man sieht, und summiere dann eben alle Werte auf, die
dieser Woche/Jahr Kombination entsprechen.

Leider gibt es immer wieder Grenzfälle, bei denen das so nicht funktioniert,
zB gehört ja bekanntermaßen der 31.12.2007 zum Jahr 2007, aber zur
Kalenderwoche 01/2008. Dieser Termin würde in meinem Statement also
überhaupt nicht erfaßt.

Da die Einführung eines komplett metrischen Kalenders ja nicht zu erwarten
ist ;o), würde ich es jetzt gern richtig machen - nur wie?

Meine Überlegung:
1. Übergabe der Kalenderwoche, zB 01/2008
2. Ermitteln, welches der erste Tag der übergebenen Woche ist =>Y hier:
31.12.2007
3. Alle Werte aufsummieren, die vom ermittelten Wochenbeginn X bis zu X+6
liegen.

Ist dieser Ansatz so richtig oder geht es auch anders? Gibt es eine
Möglichkeit, direkt in MySQL den ersten Tag der Woche zu ermitteln?

Gruß + Danke
Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 13:07:35 von Sebastian Suchanek

Erik Hastens schrieb:

> [...]
> WHERE ... AND DATE_FORMAT(date,'%v') = '$w' AND DATE_FORMAT(date,'%Y') =
> '$_GET[year]'

Ui, fein. Ich habe schon lange nicht mehr so ein schönes Scheunentor
gesehen. :-)

> Ist dieser Ansatz so richtig oder geht es auch anders?

Ich werfe mal ein "YEARWEEK" (Details nachzulesem in der Dokumentation)
in die Runde.

> Gibt es eine
> Möglichkeit, direkt in MySQL den ersten Tag der Woche zu ermitteln?

Vielleicht hilft Dir da

http://de.wikipedia.org/wiki/Kalenderwoche#Kalenderwoche

weiter.


HTH,

Sebastian

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 13:11:35 von Erik Hastens

Erik Hastens wrote:
> ...
> Ist dieser Ansatz so richtig oder geht es auch anders? Gibt es eine
> Möglichkeit, direkt in MySQL den ersten Tag der Woche zu ermitteln?


Ok, nochmaliges Suchen im Manual hat für mich nun

SELECT YEARWEEK(datum, 3 )

ergeben, was mein Problem zu lösen scheint und für ein paar überprüfte
grenzwertige Daten bis 2001 Woche und Jahr korrekt zurückgibt.

Gruß
Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 13:21:15 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 13:22:44 von Erik Hastens

Sebastian Suchanek wrote:

> Erik Hastens schrieb:
>
>> [...]
>> WHERE ... AND DATE_FORMAT(date,'%v') = '$w' AND
>> DATE_FORMAT(date,'%Y') = '$_GET[year]'
>
> Ui, fein. Ich habe schon lange nicht mehr so ein schönes Scheunentor
> gesehen. :-)

Warum? Wegen der direkten Verwendung der GET-Variable? Mal abgesehen davon,
daß die Daten wenig kritisch sind (wenn der Benutzer den angehängten
URL-Parameter ändert, sieht er eben ein anderes Jahr) - kannst Du mir einen
Hinweis geben, was daran offen ist? Mag ein wenig OT sein, aber ich lerne
gern ;o)

Ja, YEARWEEK habe ich inzwischen selbst gefunden, wobei ich nicht
hundertprozentig den Unterscheid verstehe zwischen

Modus 3 : Montag 1–53 Woche 1 ist die erste Woche mit mehr als drei Tagen
innerhalb dieses Jahres
Modus 7 : Montag 1–53 Woche 1 ist die erste Woche mit einem Montag in diesem
Jahr
und andere

Modus 3 scheint für mich ok zu sein, aber ich interpretiere das so, daß das
nicht für jedes Jahr gelten wird? Sondern ich für jedes Jahr einen anderen
Modus wählen müßte?

Gruß
Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 13:44:59 von Harald Stowasser

Erik Hastens schrieb:
> Sebastian Suchanek wrote:
>
>> Erik Hastens schrieb:
>>
>>> [...]
>>> WHERE ... AND DATE_FORMAT(date,'%v') = '$w' AND
>>> DATE_FORMAT(date,'%Y') = '$_GET[year]'
>>
>> Ui, fein. Ich habe schon lange nicht mehr so ein schönes Scheunentor
>> gesehen. :-)
>
> Warum? Wegen der direkten Verwendung der GET-Variable? Mal abgesehen
> davon, daß die Daten wenig kritisch sind (wenn der Benutzer den
> angehängten URL-Parameter ändert, sieht er eben ein anderes Jahr) -
> kannst Du mir einen Hinweis geben, was daran offen ist? Mag ein wenig OT
> sein, aber ich lerne gern ;o)

www.deinserver.de/seite?year=2007';drop table user;#'

oder so ähnlich führt zu folgendem sql:

....AND DATE_FORMAT(date,'%Y') = '2007';drop table user;#''

und jetzt darfst du mal überlegen warum immer wieder gesagt wird, das
man Eingaben NIE ungeprüft lassen darf.

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 13:46:49 von Erik Hastens

Andreas Kretschmer wrote:
> ...
> Leider hast Du scheinbar nix über SQL-Injection gefunden. Schade. Für
> Dich.

Schade finde ich eher solche arroganten Antworten.

Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 14:44:53 von mueller

Erik Hastens wrote:
> Sebastian Suchanek wrote:
>
>> Erik Hastens schrieb:
>>
>>> [...]
>>> WHERE ... AND DATE_FORMAT(date,'%v') = '$w' AND
>>> DATE_FORMAT(date,'%Y') = '$_GET[year]'
>>
>> Ui, fein. Ich habe schon lange nicht mehr so ein schönes Scheunentor
>> gesehen. :-)
>
> Warum? Wegen der direkten Verwendung der GET-Variable? Mal abgesehen
> davon, daß die Daten wenig kritisch sind (wenn der Benutzer den
> angehängten URL-Parameter ändert, sieht er eben ein anderes Jahr) - kannst
> Du mir einen Hinweis geben, was daran offen ist? Mag ein wenig OT sein,
> aber ich lerne gern ;o)
>

http://xkcd.com/327/

> Gruß
> Erik

Robert

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 14:59:43 von Sebastian Suchanek

Erik Hastens schrieb:
> Sebastian Suchanek wrote:
>
>> Erik Hastens schrieb:
>>
>>> [...]
>>> WHERE ... AND DATE_FORMAT(date,'%v') = '$w' AND
>>> DATE_FORMAT(date,'%Y') = '$_GET[year]'
>> Ui, fein. Ich habe schon lange nicht mehr so ein schönes Scheunentor
>> gesehen. :-)
>
> Warum? Wegen der direkten Verwendung der GET-Variable?

Ja, genau deswegen.

> Mal abgesehen davon,
> daß die Daten wenig kritisch sind (wenn der Benutzer den angehängten
> URL-Parameter ändert, sieht er eben ein anderes Jahr) - kannst Du mir einen
> Hinweis geben, was daran offen ist? Mag ein wenig OT sein, aber ich lerne
> gern ;o)

Dazu haben ja Harald und Robert schon etwas geschrieben.

> Ja, YEARWEEK habe ich inzwischen selbst gefunden, wobei ich nicht
> hundertprozentig den Unterscheid verstehe zwischen
>
> Modus 3 : Montag 1–53 Woche 1 ist die erste Woche mit mehr als drei Tagen
> innerhalb dieses Jahres
> Modus 7 : Montag 1–53 Woche 1 ist die erste Woche mit einem Montag in diesem
> Jahr
> und andere
>
> Modus 3 scheint für mich ok zu sein,

Modus 3 entspricht zumindest der Zählweise nach ISO 8601 - siehe auch
den Wikipedia-Artikel, den ich bereits genannt hatte.

> aber ich interpretiere das so, daß das nicht für jedes Jahr gelten wird?
> Sondern ich für jedes Jahr einen anderen Modus wählen müßte?

Nein, nach ISO 8601 - und damit vermutlich in jedem Kalender, den Du in
Deutschland zu kaufen bekommst - werden die Kalenderwochen jedes Jahr so
gezählt (KW1 ist die erste Woche mit mindestens vier Tagen im neuen
Jahr). Also spuckt auch die MySQL-Funktion jedes Jahr die "richtigen"
(im Sinn von "der offiziellen Zählweise entsprechend") aus. Ob das
Ergebnis das ist, das Du haben möchtest, mußt Du selbst wissen.


Tschüs,

Sebastian

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 16:12:44 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 19:09:59 von Claus Reibenstein

Erik Hastens schrieb:

> Andreas Kretschmer wrote:
>
>> [unwichtig]
>
> Schade finde ich eher solche arroganten Antworten.

Tipp: Filter anpassen.

Gruß. Claus

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 19:40:55 von Erik Hastens

Sebastian Suchanek wrote:
> ..
> Nein, nach ISO 8601 - und damit vermutlich in jedem Kalender, den Du
> in Deutschland zu kaufen bekommst - werden die Kalenderwochen jedes
> Jahr so gezählt (KW1 ist die erste Woche mit mindestens vier Tagen im
> neuen
> Jahr). Also spuckt auch die MySQL-Funktion jedes Jahr die "richtigen"
> (im Sinn von "der offiziellen Zählweise entsprechend") aus. Ob das
> Ergebnis das ist, das Du haben möchtest, mußt Du selbst wissen.

ok danke, dann ist es klar.

Gruß
Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 19:42:17 von Erik Hastens

Harald Stowasser wrote:
> ...
> www.deinserver.de/seite?year=2007';drop table user;#'
>
> oder so ähnlich führt zu folgendem sql:
>
> ...AND DATE_FORMAT(date,'%Y') = '2007';drop table user;#''
>
> und jetzt darfst du mal überlegen warum immer wieder gesagt wird, das
> man Eingaben NIE ungeprüft lassen darf.

OK, danke, werde es umgehend berücksichtigen ;o)

Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 05.01.2008 19:45:49 von Erik Hastens

Andreas Kretschmer wrote:
> begin Erik Hastens wrote:
>> Andreas Kretschmer wrote:
>>> ...
>>> Leider hast Du scheinbar nix über SQL-Injection gefunden. Schade.
>>> Für Dich.
>
>> Schade finde ich eher solche arroganten Antworten.
>
> Die Bewertung solcher Antworten ist Deine Sache. Aber Du hast ja
> inzwischen weitere Antworten in dieser Richtung. Von mir aus halt uns
> alle für arrogant. Ich halt sowas dann übrigens für 'lernresistent'.

Nein, ich fand die anderen Antworten hilfreich und Deine arrogant. Und wenn
diese Anmerkung bereits zum Filtern meiner Beiträge bei Dir oder anderen
führt - nun gut. Mir persönlich verdirbt so ein Umgangston ziemlich die
Motivation, in dieser NG erneut zu fragen - was für Dich natürlich eher kein
Problem ist.

Nix für ungut
Erik

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 06.01.2008 20:43:07 von Andreas Kretschmer

Andreas
--
q: why do so many people take an instant dislike to mysql?
a: it saves time (oicu in #postgresql)
Explaining the concept of referential integrity to a mysql user is like
explaining condoms to a catholic (Shadda in #postgresql)

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 07.01.2008 13:17:58 von Thomas Rachel

Harald Stowasser schrieb:

> oder so ähnlich führt zu folgendem sql:
>
> ...AND DATE_FORMAT(date,'%Y') = '2007';drop table user;#''
>
> und jetzt darfst du mal überlegen warum immer wieder gesagt wird, das
> man Eingaben NIE ungeprüft lassen darf.

Das "nicht prüfen" ist hier weniger das Problem, aber das nicht quoten
ist absolut tödlich.

Wenn man anständig quoted, sind "böswillige" Eingaben gar nicht mehr so
unheimlich problematisch.


Thomas

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 07.01.2008 13:36:46 von mueller

Thomas Rachel wrote:

> Harald Stowasser schrieb:
>
> > oder so ähnlich führt zu folgendem sql:
> >
> > ...AND DATE_FORMAT(date,'%Y') = '2007';drop table user;#''
> >
> > und jetzt darfst du mal überlegen warum immer wieder gesagt wird, das
> > man Eingaben NIE ungeprüft lassen darf.
>
> Das "nicht prüfen" ist hier weniger das Problem, aber das nicht quoten
> ist absolut tödlich.
>
> Wenn man anständig quoted, sind "böswillige" Eingaben gar nicht mehr so
> unheimlich problematisch.
>

Statt "anständigem Quoten" was erfahrungsgemäß sowieso irgendwann irgendwie
ausgetrickst werden kann, sollte man beim Übertragen von Usereingaben in
die DB eher prinzipiell auf Prepared Statements zurückgreifen.

>
> Thomas

Robert

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 07.01.2008 14:35:47 von Thomas Rachel

Robert Müller schrieb:

> Statt "anständigem Quoten" was erfahrungsgemäß sowieso irgendwann irgendwie
> ausgetrickst werden kann,

Wie trickst man mysql_real_escape_string aus?


Thomas

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 07.01.2008 14:41:35 von Thomas Rachel

Erik Hastens schrieb:

> Ok, nochmaliges Suchen im Manual hat für mich nun
>
> SELECT YEARWEEK(datum, 3 )
>
> ergeben, was mein Problem zu lösen scheint und für ein paar überprüfte
> grenzwertige Daten bis 2001 Woche und Jahr korrekt zurückgibt.

Gut. Mittels DATE_FORMAT wäre es auch möglich, und zwar mit %X/%x. (Year
for the week where Sunday/Monday is the first day of the week, numeric,
four digits; used with %V/%x)

Ist ein schwieriges Thema, man verwechselt es leicht mit dem
Kalenderjahr, wenn man nicht weit genug denkt.

Ich selbst bin schon darübergestolpert, und die "SaarBahn+Bus GmbH"
kennt das Problem nun auch - sie waren nicht in der Lage, für KW 01/2008
korrekte Wochenkarten auszugeben. (Meine lautete auf 01/2007; ich mußte
sie zurückgeben und an den Automaten der DB AG gehen, um eine korrekte
zu erhalten...)


Thomas

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 07.01.2008 14:43:58 von Andreas Kretschmer

Andreas
--
Andreas Kretschmer
Linux - weil ich es mir wert bin!
GnuPG-ID 0x3FFF606C http://wwwkeys.de.pgp.net
Deutsche PostgreSQL User Group: http://pgug.de

Re: Alle Jahre wieder: 31.12.2007 in KW 01/2008

am 07.01.2008 14:59:59 von Thomas Rachel

Andreas Kretschmer schrieb:

> PHP hat sich ja in den letzten Jahren nicht wirklich mit Ruhm
> bekleckert.

ich redete nicht von PHP.

> Außerdem geht es hier auch nicht um PHP, sondern um MySQL.

Und um die Funktionen der zugehörigen C-API, wovon
mysql_real_escape_string() eine ist.


> Und die generische Lösung mit den Mitteln der DB ist nun einmal das, was
> Du in Deinem Quoting geschickt unterschlagen hast: Prepared Statements.

Auch eine Möglichkeit, ja. Die genannte Funktion wird jedoch ebenfalls
von MySQL zur Verfügung gestellt, ist also ebenfalls eine offiziell
vorgesehene Lösung.

http://dev.mysql.com/doc/refman/5.0/en/mysql-real-escape-str ing.html

Angenommen, die Funktion wurde korrekt implementiert, ist ihre Anwendung
genauso sicher, jedoch einfacher anzuwenden als die von Prepared
Statements, für die es unter

http://dev.mysql.com/doc/refman/5.0/en/mysql-stmt-execute.ht ml

ein Beispiel gibt.


YMMV.


Thomas