Autor | Zpráva | ||
---|---|---|---|
Amunak Profil |
#1 · Zasláno: 20. 6. 2010, 21:32:23 · Upravil/a: Amunak
Nikdy jsem neskládal nějaký složitější dotaz. Jak mám udělat, aby se při tomto příkazu
UPDATE `chatter_users` SET `online` = 0 WHERE `last_active`+1800 < UNIX_TIMESTAMP() AND `online` = 1 vykonalo ještě INSERT INTO `chatter_chatboard` (time, user_id, user, message) VALUES ('UNIX_TIMESTAMP()', 0, 'System', 'Uživatel <jméno> byl odhlášen ze systému za dlouhodobou neaktivitu.') <jméno> chci nahradit polem `user` v `chatter_users` právě tím jménem, kterému jsem nastavil online na 0. Díky za pomoc. |
||
Kajman_ Profil * |
#2 · Zasláno: 20. 6. 2010, 21:58:34
Máte-li možnost triggerů, tak to půjde přes něj.
Jinak select uživatelů, co se mají odhlásit. Pak je odhlásit updatem a insertnout do chatu. |
||
Alphard Profil |
#3 · Zasláno: 20. 6. 2010, 22:05:25
Jestli nemáte triggery a chcete šetřit dotazy, mohlo by to jít takhle.
insert into chatter_chatboard (time, user_id, user, message) select UNIX_TIMESTAMP(), 0, 'System', concat('Uživatel ', user, ' byl odhlášen ze systému za dlouhodobou neaktivitu.') from `chatter_users` SET `online` = 0 WHERE `last_active`+1800 < UNIX_TIMESTAMP() AND `online` = 1; UPDATE `chatter_users` SET `online` = 0 WHERE `last_active`+1800 < UNIX_TIMESTAMP() AND `online` = 1 |
||
Amunak Profil |
#4 · Zasláno: 20. 6. 2010, 22:18:58
Kajman:
Triggerům bych se rád vyhnul. Jak to udělat přes ten select? Hlavně bych se rád vyhnul ještě zpracování v PHP, protože při větším počtu uživatelů by se to mohlo poněkud zpomalovat, není-liž pravda? Alphard: Díky, něco takového potřebuji, ale váš dotaz bohužel nefunguje. Nemá být to za tím selectem v závorkách? Zkoušel jsem to nějak upravit, ale nepovedlo se. Ještě mě napadá, že v tom prvním dotazu přebývá SET `online` = 0 |
||
Alphard Profil |
#5 · Zasláno: 20. 6. 2010, 22:27:54
[#4] Amunak
Přebývá, kopíroval jsem to a asi jsem zatáhl kurzorem moc do strany. Bez toho to jde? |
||
Amunak Profil |
#6 · Zasláno: 20. 6. 2010, 22:32:25
Alphard, Alphard:
no jo, jde! Super, díky! |
||
Amunak Profil |
#7 · Zasláno: 20. 6. 2010, 22:44:36
Ještě mě napadá - jak to opodmínkovat přes IF tak, aby se to vykonalo pouze když
SELECT * FROM `chatter_misc` WHERE `variable` = last_maintenance +300 < UNIX_TIMESTAMP() ? V té tabulce si vlastně vždy ukládám "proměnné" a jejich "hodnoty". Tak bych to z toho potřeboval vytáhnout a ještě nacpat do IF STATEMENT. |
||
Alphard Profil |
#8 · Zasláno: 20. 6. 2010, 22:47:50
Třetí tabulka? Je mi líto, ale nechápu strukturu a vztahy.
|
||
Amunak Profil |
#9 · Zasláno: 20. 6. 2010, 22:55:33
Alphard:
Jen potřebuji do IF nějak zapracovat získání hodnoty ze sloupce value z tabulky `chatter_misc`kde se sloupec variable rovná 'last_maintenance'. K této hodnotě pak přičíst 300 (5minut) a porovnat to s aktuálním časem. Chci tím docílit toho, aby se před tím šíleným dotazem nejprve zkontrolovalo, kdy byl naposledy vykonán, a pokud to bylo dříve jak před pěti minutami, tak to ignorovat. |
||
Alphard Profil |
#10 · Zasláno: 21. 6. 2010, 00:09:06
Už rozumím, ale neporadím. Nevím, jestli to vůbec půjde dát do jednoduchého dotazu, zkuste se podívat na Větvení uložených procedur.
Zvažte možnost, že byste to ukládal do souboru. |
||
Amunak Profil |
#11 · Zasláno: 21. 6. 2010, 00:34:49
Alphard:
Asi to prostě nebudu dělat složitě - buď to úplně vynechám a spustím to třeba cronem nebo při každém přihlášení a odhlášení nějakého uživatele (místo spuštění s kontrolou třeba po každém napsání příspěvku), nebo tu kontrolu a podmínku zpracuji v php. Tu nejhorší část (nejzatěžovanější) mám v MySQL, a to je důležité. Ještě jednou díky. |
||
Kajman_ Profil * |
#12 · Zasláno: 21. 6. 2010, 09:11:00
Amunak:
„Jak to udělat přes ten select?“ Do proměnné v php si dát výsledek select group_concat(`user_id`) as seznam_id from `chatter_users` WHERE `last_active` < UNIX_TIMESTAMP()-1800 AND `online` = 1 A pak dva dotazy insert into chatter_chatboard (time, user_id, user, message) select UNIX_TIMESTAMP(), 0, 'System', concat('Uživatel ', user, ' byl odhlášen ze systému za dlouhodobou neaktivitu.') from `chatter_users` WHERE user_id in ($seznam_id); UPDATE `chatter_users` SET `online` = 0 WHERE user_id in ($seznam_id); Místo proměnné v php lze použít i temporary tabulku. Jinak Alphardovu verzi je lepší uzavřít do transakce, aby se zamezilo možnosti nekonzistence logu a stavu online. |
||
Alphard Profil |
#13 · Zasláno: 21. 6. 2010, 09:43:47
„do transakce, aby se zamezilo možnosti nekonzistence logu a stavu online“
V tomto případě by asi také mohlo stačit dát v php $time = time(); a $time pak dasadit do obou dotazů. Na zprávy chatu to bude dostatečně přesné a jednodušší. Myslel jsem na to a zapomněl to napsat :-). |
||
Amunak Profil |
#14 · Zasláno: 21. 6. 2010, 10:54:35
Kajman:
Použiju tu Alphardovu verzi - PHP se o to pak nemusí vůbec starat, a to je to, o co mi jde. Ale jak vidím, stejně se s těmi transakcemi budu muset naučit. Ale zase na druhou stranu, tohle není nijak zásadní a když se to neprovede poprvé, provede se to podruhé a nic se nestane. |
||
Kajman_ Profil * |
#15 · Zasláno: 21. 6. 2010, 11:17:44
Amunak:
Tak si alespoň přepište podmínku `last_active`+1800 < UNIX_TIMESTAMP() na `last_active` < UNIX_TIMESTAMP()-1800 |
||
Časová prodleva: 14 let
|
0