Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
ckoepp
- Beiträge: 1409
- Registriert: 11.06.2005 20:11:23
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Nähe Heidelberg
Beitrag
von ckoepp » 06.12.2006 09:20:45
Hallo zusammnen,
hab ein kleines Problem mit einer SQL Abfrage und komm einfach nicht auf die Lösung.
Ziel von dem Ganzen soll sein beim user 'xzy' einen fixen Wert als Ergebnis der Abfrage zu liefern. Bei Usern die
nicht xyz sind, soll die Abfrage ausgeführt werden. Das muss direkt in der SQL-Abfrage geschehen.
Derzeit liefert die folgende Abfrage entweder einen oder keinen Wert (falls user = 'xyz') aus. Aber ich brings einfach nicht hin da einen fixen Wert auszugeben wenn der user 'xyz' ist.
Code: Alles auswählen
SELECT myvar FROM mytable WHERE user='%u%' AND '%u%' != 'xyz' ORDER BY time DESC LIMIT 1;
%u% steht hier für den Usernamen und wird ausgetauscht
"Es gibt kein Problem, das man nicht mit einem doppelten Scotch lösen könnte!"
Ernest Hemingway
-
tylerD
- Beiträge: 4068
- Registriert: 10.07.2002 17:34:13
- Wohnort: Halle/Saale
-
Kontaktdaten:
Beitrag
von tylerD » 06.12.2006 09:26:43
Wenn eh immer nur ein Wert zurückgegeben wird, warum trägst du nicht einfach den fixen Wert als eine Zeile in die DB und behandlst den User xyz genau wie die anderen?
Gruß,
Mirko
edit: Ansonsten ein Konstrukt ähnlich wie
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 06.12.2006 10:55:04
Die Frage von typerD ist sicherlich berechtigt
Ansonsten mußt du das select-Statement so umbauen, daß auch für den User 'xyz' zumindest ein Datensatz zurückgeliefert wird.
Bei DB2 würde sich da z.B. die Tabelle sysibm.sysdumm1 anbieten:
z.B.
Code: Alles auswählen
select T.myvar from mytable T where T.user='%u%' and T.user!='xyz' union
all select 'fixer Wert' from sysibm.sysdummy1 where 'xyz'='%u%'
bei Oracle könntest du z.B. die "dual" Tabelle verwenden.
oder du erzwingst über die Gruppierung, die Rückgabe des fixen Wertes:
Code: Alles auswählen
select T.myvar from mytable T where T.user='%u%' and T.user!='xyz' union
all select 'fixer Wert' from mytable having 'xyz'='%u%'
Gruß
gms
-
ckoepp
- Beiträge: 1409
- Registriert: 11.06.2005 20:11:23
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Nähe Heidelberg
Beitrag
von ckoepp » 06.12.2006 13:38:28
tylerD hat geschrieben:Wenn eh immer nur ein Wert zurückgegeben wird, warum trägst du nicht einfach den fixen Wert als eine Zeile in die DB und behandlst den User xyz genau wie die anderen?
Leider nicht möglich (oder eben sehr sehr unschön), da diese Tabellen Log(-files) sind. Eine Veränderung des Ganzen müsste dann wieder im Webinterface berücksichtigt werden.
Es ist nicht ganz schön das per SQL so zu realisieren, aber wie so oft der schnellste und einfachste Weg
Werde mal das IF probieren, hab insowas keine Erfahrung mit SQL. Über INNER JOINS bin ich nie rausgekommen
"Es gibt kein Problem, das man nicht mit einem doppelten Scotch lösen könnte!"
Ernest Hemingway
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 06.12.2006 16:15:39
ckoepp hat geschrieben:
Werde mal das IF probieren, hab insowas keine Erfahrung mit SQL
Vielleicht habe ich mich nicht deutlich genug ausgedrückt:
Die IF-Abfrage als Column-Expression setzt vorraus, daß "myvar" für den User 'xyz' gleich NULL ist und für ALLE anderen User "not NULL" ist.
Diese Vorraussetzung mag ja noch kein großes Problem sein, leider wird aber auch vorrausgesetzt, daß die Ergebnismenge für die Abfrage nach dem User 'xyz' größer oder gleich 1 ist und das schaffst du nur mit einem "zusätzlichen Konstrukt" ( "OUTER JOIN" oder "UNION" oder "Table-Expression" oder "Column-Expression mit Selectstatement", ...).
Sobald du aber so ein "zusätzliches Konstrukt" verwendest, wird wiederum diese IF-Abfrage nicht mehr benötigt, wie mein obiges Beispiel verdeutlichen sollte.
Gruß
gms
-
tylerD
- Beiträge: 4068
- Registriert: 10.07.2002 17:34:13
- Wohnort: Halle/Saale
-
Kontaktdaten:
Beitrag
von tylerD » 06.12.2006 19:11:57
Muss gms recht geben. Evt. geht das mit dem IF, aber auf jeden Fall klingt deine (techn.) Anforderung extrem nach Quick-and-Dirty Hack und du hast bestimmt irgendwo in deiner Anwendungslogik oder im Datenbankstruktur ein Designfehler.
Gruß,
Mirko
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 06.12.2006 19:30:29
tylerD hat geschrieben:Evt. geht das mit dem IF
Ich wollte keinesfalls den Eindruck erwecken, daß es mit dem IF nicht funktioniert, Daher hier eine entsprechende Lösung unter DB2 (daher mit "coalesce", als "if"-Ersatz) und einem OUTER JOIN:
Code: Alles auswählen
gms@gms1:~$ db2 "select coalesce(T.myvar,'fixer wert') var from sysibm.sysdummy1 left outer join mytable T on T.user='xyz'"
VAR
------------------------------
fixer wert
1 record(s) selected.
gms@gms1:~$ db2 "select coalesce(T.myvar,'fixer wert') var from sysibm.sysdummy1 left outer join mytable T on T.user='gms'"
VAR
------------------------------
hallo
1 record(s) selected.
@ckoepp
eigentlich wollte ich dir nur verdeutliche, daß das IF nur die "halbe Miete" ist
Gruß
gms
-
ckoepp
- Beiträge: 1409
- Registriert: 11.06.2005 20:11:23
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Nähe Heidelberg
Beitrag
von ckoepp » 07.12.2006 15:56:36
tylerD hat geschrieben:Muss gms recht geben. Evt. geht das mit dem IF, aber auf jeden Fall klingt deine (techn.) Anforderung extrem nach Quick-and-Dirty Hack und du hast bestimmt irgendwo in deiner Anwendungslogik oder im Datenbankstruktur ein Designfehler.
Dann mail das mal an
team@proftpd.org
Das Ganze logt die Einlogvorgänge auf einem anonymous account. Und da ich nur eine Config für alle haben darf (oder eben IP-based vhots - ftp eben) muss die SQL Anweisung für alle gültig sein. D.h. alle User sollen den letzten Loginvorgang sehen bis auf anonymous. Wäre nicht so prickelnd wenn jeder sehen könnte wer das letzte Mal eingelogt war und von wo
Bisher wird in der Login-Message immer [null] zurückgegeben (siehe SQL Anweisungen oben). Schön wärs halt wenn ich es hinbekommen würde das 127.0.0.1 als IP und das derzeitige Datum drinstehenn würde.
Ohne selbst im proftpd-source zumzuhacken wird das wohl nicht änderbar sein.
"Es gibt kein Problem, das man nicht mit einem doppelten Scotch lösen könnte!"
Ernest Hemingway
-
ckoepp
- Beiträge: 1409
- Registriert: 11.06.2005 20:11:23
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Nähe Heidelberg
Beitrag
von ckoepp » 07.12.2006 18:47:28
Hab es so gelöst:
Code: Alles auswählen
SELECT IF('%u%' != 'xyz', myvar, '127.0.0.1') FROM mytable WHERE user='%u%' ORDER BY time DESC LIMIT 1;
Funktioniert prima, allerdings werd ich mal an die Entwickler von proftpd schreiben. Eigentlich könnte man die ganzen SQL-Funktionen schon etwas besser ausstatten. Es ist nichtmal möglich mehrere SQL-Anweisungen einem Event zuzuweisen
"Es gibt kein Problem, das man nicht mit einem doppelten Scotch lösen könnte!"
Ernest Hemingway
-
gms
- Beiträge: 7798
- Registriert: 26.11.2004 20:08:38
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von gms » 07.12.2006 19:27:32
ckoepp hat geschrieben:Ziel von dem Ganzen soll sein beim user 'xzy' einen fixen Wert als Ergebnis der Abfrage zu liefern.
Dieses Ziel wird bei deiner derzeitigen Abfrage nur dann erreicht, wenn für den User 'xzy' zumindest ein Datensatz in der Tabelle existiert.
Ob diese Bedingung immer erfüllt ist, oder dein Ziel einfach nur ungenau definiert wurde, kann ich nicht beurteilen
Gruß
gms
-
ckoepp
- Beiträge: 1409
- Registriert: 11.06.2005 20:11:23
- Lizenz eigener Beiträge: MIT Lizenz
- Wohnort: Nähe Heidelberg
Beitrag
von ckoepp » 08.12.2006 11:37:15
gms hat geschrieben:Dieses Ziel wird bei deiner derzeitigen Abfrage nur dann erreicht, wenn für den User 'xzy' zumindest ein Datensatz in der Tabelle existiert.
Ob diese Bedingung immer erfüllt ist, oder dein Ziel einfach nur ungenau definiert wurde, kann ich nicht beurteilen
Das ist klar, daher wird auch beim Anlegen des Users automatisch ein Datensatz in die DB geschrieben.
Muss leider wie gesagt da etwas tricksen, proftpd lässt da keine großen Spielräume
"Es gibt kein Problem, das man nicht mit einem doppelten Scotch lösen könnte!"
Ernest Hemingway