Portál AbcLinuxu, 5. listopadu 2025 12:42
UPDATE vzkazy_data as text
SET dorucenka_vzkazy_data = 'f'
FROM (
SELECT id_vazby_vzkazy_vazebni, dorucenka_vzkazy_data, cas_zpravy_vzkazy_data, nick_uzivatele, id_uzivatele,text_vzkazy_vazebni
FROM vzkazy_data
JOIN vzkazy_vazebni ON id_vzkazu_vzkazy_data = id_vazby_vzkazy_vazebni
JOIN uzivatele ON id_odesilatel_vzkazy_data = id_uzivatele
WHERE (id_odesilatel_vzkazy_data = 1 AND id_adresat_vzkazy_data = 9)
OR (id_odesilatel_vzkazy_data = 9 AND id_adresat_vzkazy_data = 1)
ORDER BY cas_zpravy_vzkazy_data DESC
LIMIT 10 OFFSET 0
FOR UPDATE
) AS nezobrazeno
WHERE id_vazby_vzkazy_vazebni = nezobrazeno.id_vazby_vzkazy_vazebni;
RETURNING text_vzkazy_vazebni,
nezobrazeno.cas_zpravy_vzkazy_data,
nezobrazeno.nick_uzivatele,
nezobrazeno.id_uzivatele,
nezobrazeno.dorucenka_vzkazy_data;
ale vypisuje to nesmysly... tohle zrovna vypíše 200x první řádek té konverzace a updatuje celou tabulku. mohl by mi někdo s tím píchnout? děkuji
UPDATE vzkazy_data as text
SET dorucenka_vzkazy_data = 'f'
FROM (
SELECT id_vazby_vzkazy_vazebni, dorucenka_vzkazy_data, cas_zpravy_vzkazy_data, nick_uzivatele, id_uzivatele,text_vzkazy_vazebni
FROM vzkazy_data
JOIN vzkazy_vazebni ON id_vzkazu_vzkazy_data = id_vazby_vzkazy_vazebni
JOIN uzivatele ON id_odesilatel_vzkazy_data = id_uzivatele
WHERE (id_odesilatel_vzkazy_data = 1 AND id_adresat_vzkazy_data = 9)
OR (id_odesilatel_vzkazy_data = 9 AND id_adresat_vzkazy_data = 1)
ORDER BY cas_zpravy_vzkazy_data DESC
LIMIT 10 OFFSET 0
FOR UPDATE
) AS nezobrazeno
WHERE id_vazby_vzkazy_vazebni = nezobrazeno.id_vazby_vzkazy_vazebni;
RETURNING text_vzkazy_vazebni,
nezobrazeno.cas_zpravy_vzkazy_data,
nezobrazeno.nick_uzivatele,
nezobrazeno.id_uzivatele,
nezobrazeno.dorucenka_vzkazy_data;
CREATE TABLE uzivatele (
id_uzivatele BIGSERIAL primary key,
nick_uzivatele CITEXT UNIQUE not null,
heslo_uzivatele VARCHAR(255) not null
);
CREATE TABLE vzkazy_data (
id_vzkazu_data BIGSERIAL primary key,
id_odesilatel_vzkazy_data BIGSERIAL not null,
id_adresat_vzkazy_data BIGSERIAL not null,
dorucenka_vzkazy_data boolean not null,
vymazani_vzkazy_data SMALLINT not null,
cas_zpravy_vzkazy_data TIMESTAMP not null,
id_vzkazu_vzkazy_data BIGSERIAL not null
);
CREATE TABLE vzkazy_vazebni (
id_vazby_vzkazy_vazebni BIGSERIAL primary key,
text_vzkazy_vazebni VARCHAR(5000) not null
);
Proč je v tabulce vzkaky_vazebni nějaké id_vazby, když ta tabulka obsahuje jako jedinná další data text zprávy? Název pole nekoresponduje ani s názvem tabulky, ani s jejím obsahem.
Až todle všechno uděláš a napíšeš si ten dotaz znovu, tak snadno uvidíš, kde byl problém a proč to píše tu chybovou hlášku v případě, že tam doplníš to text, aby id_vazby_vzkazy_vazebni nebral z tabulky nezobrazeno. Pak opravíš dotaz, vyzkoušíš... a pak Ti zbývá pouze poslední krok:
4) Zamyslíš se nad strukturou tabulek - Jaký má význam, aby byly odděleny tabulky
vzkazy_data a vzkazy_vazební, když je tam evidentně relace 1:1? - a celý to zjednodušíš a přepíšeš
Doporučuju ale krok čtyři udělat opravdu jako poslední, ať to příště neuděláš zas takhle s odpuštěním strašně
Jestli Ti cokoli není jasný, tak se klidně ptej, rád Ti s tím pomůžu.
...
id_odesilatel_vzkazy_data BIGINT not null,
id_adresat_vzkazy_data BIGINT not null,
...
0) ty cizí klíče jsem ani nevěděl že něco takového existuje, ale jak si o tom čtu tak to tam nemusim mít ne? je to jenom pro integritu. doplním to tam, ale napřed chci pochopit tu logiku protože to může mít následky když to tam nasekám nesprávně. Viz bod 4 např.
1) no já myslel že je vazební. :D a ona to je nakonec ta druhá.
2 & 3) celý je to zmateční. teprve přicházim na systém. ale co se bodu 2 týče... můžu pak někdy časem chtít joinovat i něco co neni cizí klíč a to se může jmenovat stejně jako něco jinýho co už budu selectovat.
4) tohle ale má zásadní důvod. když budu chtít odeslat hromadnou zprávu měl bych jí tam třeba 1000x takhle na ní můžu jenom odkázat. proto taky jsem jí pojmenoval vazební tuhle tabulku, což vlastně si uvědomuju, že opravdu má být obráceně. Slibuju že to přejmenuju, ale napřed to chci rozchodit takhle abych to nějak chápal.
...ale podle nápovědy jsem pochopil, že problém je někde v tom že je někde něco špatně přehozeno, ale stejně to nemůžu najít. ten vnitřní select je správně a dál už nevim co by mohlo bejt v tom uploadu špatně. prostě se s tím setkávám prvně.
(A to neřeším případ, kdy vážeš dvě stejné tabulky na sebe, kde pak musíš alias tak jako tak uvést - což je vlastně i případ toho Tvého dotazu).
4) Jo aha, netušil jsem, že píšeš systém pro spammery, to bych Ti nepomáhal vůbec
V tom případě ale má stejně zpráva jednoho odesílatele a čas odeslání a jeden text, jediný, čeho může bejt víc, je snad příjemce a příznak vymazání, ne? Takže i tak by ta struktura měla vypadat jinak.
ad Chyba) Pojmenuj rozumně ty tabulky a sloupce. Protože je to IMHO jedinná možnost, jak na to přijít. Když to budeš mít pojmenovaný normálně, tak si ten dotaz jednou přečteš a bude Ti to jasný. A až na to příjdeš, můžeš vždycky se vrátit k tý současný a kouknout se, jak to teda původně mělo bejt.
Přehlednost návrhu a názvů je jedním ze základních programátorských dovedností - to neni tak, že dobrej programátor se vyzná ve zmatku. Dobrej programátor zmatek neudělá a nebo aspoň když udělá, tak opraví. A pokud něco nefunguje a je tam zmatek v názvech, tak je naprosto standardní postup vhodným pojmenováním si nejprve udělat jasno, co je vlastně co - chyba se pak vyloupne sama. Např. když budeš mít program
Pes a ;
Kočka b ;
Papoušek c ;
...
b.stekej()
Tak můžeš chybu hledat hodinu a nevšimneš si toho. Jedinná šance, jak ji najít je si proměnné dobře pojmenovat, tj. a pes, b kočka atd... A to můžeš udělat buďto jen v hlavě - to ale zvládneš takhle pobrat jen kousek kódu a ten Tvůj dotaz je dost dlouhej i pro zkušenýho programátora, nebo když je to možný i přímo v kódu.
Zmatek v názvech je IMHO naprosto stejná chyba, jako špatně napsaný dotaz. Sice to sice samo o sobě žádnou "reálnou chybu" neudělá, ale generuje to chyby jak na běžícím pásu. Ono umění programovat je v podstatě umění dávat proměnným správný jména. Algoritmus, pokud věci správně pojmenuješ, se zpravidla vyloupne sám (trochu přehánim, ale ne moc).
UPDATE vzkazy_data as zobrazeno
SET dorucenka = 'f'
FROM (
SELECT id_vazby, dorucenka, cas_zpravy, nick, id, text
FROM vzkazy_data
JOIN vzkazy_vazebni ON id_vzkazu = id_vazby
JOIN uzivatele ON id_odesilatel = id
WHERE (id_odesilatel = 1 AND id_adresat = 9)
OR (id_odesilatel = 9 AND id_adresat = 1)
ORDER BY cas_zpravy DESC
LIMIT 10 OFFSET 0
FOR UPDATE
) AS nezobrazeno
RETURNING text,
nezobrazeno.cas_zpravy,
nezobrazeno.nick,
nezobrazeno.id,
nezobrazeno.dorucenka;
a nestalo se nic slíbeného. neni mi to jasný.
JOIN vzkazy.id_text_vzkazu = text_vzkazu.id
je na prvni pohled videt, jestli to je nebo neni dobre. Z tech divokejch nazvu ne.
A chybí tam podmínka WHERE, což je klíčový, protože v tý je ta chyba.
A taky moc nechápu, proč se aliasy jmenují zobrazeno a nezobrazeno. Zkus je pojmenovat tak, aby bylo jasné, co je to za kus dat. Rozhodne vnitrni select vybira data za nejakym ucelem (a rozhodne ne proto, aby je nezobrazil), vnejsimu selectu bych alias klidne vubec nedaval, defakto tim zduraznis, ktera tabulka je ta hlavni, tj. upravovana.
Jinak bych doporučil, jestli máš patřičnou verzi postgresu, která to umí,
dotaz napsat způsobem
WITH updated AS
(
UPDATE ...
RETURNING id
)
SELECT blablabla FROM
asdasdasd
JOIN UPDATED ON vzkazy_data.id = updated.id
Tedy oddělit část vybírající provádějící úpravu a část dělající select upravených dat, zvýšíš tím čitelnost - ale to jde tuším až od některý verze postgresu (tuší 9.1).
Zkus to ještě jednou, nevěřím, že když to rozumně pojmenuješ a pak si dotaz ještě jednou projdeš, že to nenajdeš. Když i tak ne, tak Ti to samozřejmě prozradím
Ale co jsem se tím zaobíral, tak je to podle mě chyba fakt způsobená tím, že ses zamotal do názvů tabulek a sloupců a vážeš spolu někde něco, co nemáš.
ON vzkazy.text_vzkazu_id = text_vzkazu.id
A opravdu IMHO když si to pojmenuješ dobře, tak na to musíš přijít, protože právě ta konvence výš zajišťuje, že jsou obě strany přiřazení, když vážeš tabulky (ať v ON nebo WHERE) defakto shodné a tak je dobře vidět, když se váže něco, co se vázat nemá...
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.