NOT IN NULL vrací prázdný výsledek
- Lavka
- Člen | 8
Dobrý den,
narazil jsem na problém ohledně používání IS NOT v Nette/Database.
Přesněji jde o to že když dotaz vrátí IS NOT NULL tak se vrátí
prázdný výsledek.
...
->where("id NOT",$this->connection->table("share")....)
...
to jsem vyřešil tím že jsem dotaz z tabulky share položil dřív a pak ho projel:
$notShow = "0";
foreach($result as $note) {
$notShow .= ",".$note->task_id;
}
Toto řešení fungovalo do té doby, než jsem začal ajaxovat aplikaci a tento dotaz se vykonal dřív než proběhlo volání handlu. A tak se vrátilo ajaxem to samé co předtím. Kód pro vykreslení seznamu mám v komponentě, takže dotaz předávám jako parametr při jeho volání, z toho důvodu bych potřeboval celý tento kód umístit do toho dotazu, který předávám do komponenty a provádí se až při renderování šablony.
- petr.pavel
- Člen | 535
To není chyba Nette Database. NOT IN (NULL)
prostě vrací
false, IN (NULL)
(bez negace) taky. Tak se chová MySQL.
Jestli ti dobře rozumím, chtěl bys, aby
$this->connection->table(„share“) vracelo $vysledek, který by pak
v kontextu where("id NOT", $vysledek)
vždycky vrátil true. A to
dost dobře nejde, protože žádná taková univerzální hodnota neexistuje.
NDB nemůže vědět, v jakém kontextu to voláš, aby třeba někdy vrátilo
0 a někdy null.
Řešením je vyčlenit poddotaz:
...
$shares = $this->connection->table("share")....;
if ($shares) {
...->where("id NOT",$shares);
}
...
- nanuqcz
- Člen | 822
Není to hezké řešení, ale tyhle problémy s NDB řeším tak, že mu „vnutím“ vlastní SQL dotaz:
// Získat všechny články, které neobsahují žádné komentáře označené jako spam
$db->table('article')
->where('
article.id NOT IN (
SELECT `article_id` FROM `article_post` WHERE `article_id` = `article`.`id` AND `spam` = 1
)');
Možná někdo poradí hezčí řešení, každopádně tohle funguje :-)
Editoval nanuqcz (9. 3. 2013 13:56)
- duke
- Člen | 650
petr.pavel napsal(a):
To není chyba Nette Database.
NOT IN (NULL)
prostě vrací false,IN (NULL)
(bez negace) taky. Tak se chová MySQL.
Chyba Nette Database to rozhodně je. Chybou je právě to, že Nette
Database interně používá výraz IN (NULL)
, který není
ekvivalentní k IN ()
. Potíž je v tom, že zápis
IN ()
se v SQL použít nedá.
Už se to řešilo na githubu zde a zde.
Zatím jsme došli k tomu, že nejlepším řešením je upravit Nette\Database tak, aby nahrazovala:
(expr) IN ()
výrazem
(expr) IS NULL AND FALSE
a
(expr) NOT IN ()
výrazem
(expr) IS NULL OR TRUE
Bude to vracet hodnoty, které jsou očekávané, a přitom se zachová jak
syntaktická kontrola výrazu expr
, tak jeho případný
vedlejší efekt.