Oznámení
WHERE %and vs NULL (MySQL)
před 11 lety
- phx
- Člen | 652
Zdravim…
Narazil jsem na problem. Kdyz do Dibi poslu napr SQL:
$array = array('name'=>null);
dibi::query('SELECT * FROM [table] WHERE %and', $array);
tak mi to vrati SQL:
SELECT * FROM `table` WHERE `name`=NULL
Coz nic nenajde protoze spravne to je:
SELECT * FROM `table` WHERE `name` IS NULL
Reseni je jedine v zasahu do dibi nebo sestavovat dotaz rucne.
Dale pokud $array = array()
SQL je:
SELECT * FROM `table` WHERE `name`
Osobne bych cekal, ze to bude:
SELECT * FROM `table` WHERE 1
Ale to je drobnost. To prvni me trapi hodne.
Dale me napada, ze by mozna stalo za to realizovat podporu pro IN (…) a
LIKE.
Napriklad takto:
$array = array(
'id%in'=>array(1, 2, 3)
);
dibi::query('SELECT * FROM [table] WHERE %and', $array);
// SELECT * FROM `table` WHERE `id` IN (1, 2, 3)
$array = array(
'name%like'=>'phx%'
);
dibi::query('SELECT * FROM [table] WHERE %and', $array);
// SELECT * FROM `table` WHERE `name` LIKE 'phx%'
Editoval phx (18. 8. 2008 13:20)
před 11 lety
- phx
- Člen | 652
Zadna reakce?
před 11 lety
- David Grudl
- Nette Core | 6806
phx napsal(a):
SELECT * FROM `table` WHERE `name`=NULL
opraveno.
Osobne bych cekal, ze to bude:
SELECT * FROM `table` WHERE 1
Opraveno.
Dale me napada, ze by mozna stalo za to realizovat podporu pro IN (…) a LIKE.
Napriklad takto:$array = array( 'id%in'=>array(1, 2, 3) ); dibi::query('SELECT * FROM [table] WHERE %and', $array); // SELECT * FROM `table` WHERE `id` IN (1, 2, 3) $array = array( 'name%like'=>'phx%' ); dibi::query('SELECT * FROM [table] WHERE %and', $array); // SELECT * FROM `table` WHERE `name` LIKE 'phx%'
To jsou výborné nápady, ale šel bych ještě o kousek dál: prostě
rozšířit klíč o operátor. Otázkou je, jak ho oddělit – co třeba
mezerou? Prostě 'klic%modifikator operator'
. Takže třeba
$array = array(
'id%l IN'=>array(1, 2, 3) // %l je modifikátor pro list, IN je operátor
);
dibi::query('SELECT * FROM [table] WHERE %and', $array);
// SELECT * FROM `table` WHERE `id` IN (1, 2, 3)
$array = array(
'name% LIKE'=>'phx%' // modifikátor vynecháme, jen operátor LIKE
);
dibi::query('SELECT * FROM [table] WHERE %and', $array);
// SELECT * FROM `table` WHERE `name` LIKE 'phx%'
před 11 lety
- phx
- Člen | 652
Hezky, ale nejak me nenapada vyhoda (vyuziti) oddeleni modifikatoru od klice.
před 11 lety
- David Grudl
- Nette Core | 6806
Jak to myslíš?
před 11 lety
- phx
- Člen | 652
Proste nenapada me k cemu by to bylo dobre:
'klic%modifikator operator'
před 11 lety
- phx
- Člen | 652
Nevim, mozna SQL neznam dobre ztak jak jsem si myslel, ale u IN jsou vzdy
data v zavorkach oddelene carkou a ohledne LIKE nevidim vyhodu toho, ze na to
mohu pouzit nejaky modifikator. Osobne by mi prislo logictejsi:
id%in
a name%like
Chci tim take rict, ze mohou vznikat konstrukce jako id%a IN
coz
si nedovedu predstavit v SQL.
před 11 lety
- David Grudl
- Nette Core | 6806
Ono jde spíš o to, že těch operátorů existuje hodně, navíc kromě IN a LIKE může být třeba NOT IN, NOT LIKE atd. Účelem modifikátoru je říct, jak hodnotu vložit do SQL, nikoliv co se s ní bude provádět, a tak by to asi mělo zůstat.
Pro začátek rozšířím %and
a %or
tak, aby
generovalo
$array = array(
'id%l' => array(1, 2, 3)
);
dibi::query('SELECT * FROM [table] WHERE %and', $array);
// SELECT * FROM `table` WHERE `id` IN (1, 2, 3)
tedy zachovám jim vlastnost porovnávání, tedy přes operátory
=
, IS
nebo IN
. Implementace jiných
operátorů bude vyžadovat trošku hlubší analýzu.
před 11 lety
- PetrP
- Člen | 587
Tohle ještě není funkční nebo dělám něco špatně?
před 11 lety
- phx
- Člen | 652
Potreboval bych v poli definovat nejak NOT.
SELECT COUNT(*) FROM tabulka WHERE neco <> 10
SELECT COUNT(*) FROM tabulka WHERE neco NOT IN (10, 20, 30)
Predstava:
$where = array(
'~neco'=>10,
);
// nebo
$where = array(
'~neco'=>array(10, 20, 30)',
);
Nebo to nejak jde?
před 11 lety
- phx
- Člen | 652
Pohnul se vyvoj nejak? NOT by se mi hodilo…
Pokud by jsi chtel pomoci s vyvojem staci rict.
před 11 lety
- blacksun
- Člen | 181
K tomuto bych měl dotaz, jestli se dá nějak pracovat s polem podmínek, kde nejde o rovnost, ale větší menší apod., např. datum > 2008–10–10 AND datum < 2009–01–01.
před 11 lety
- David Grudl
- Nette Core | 6806
phx napsal(a):
Pohnul se vyvoj nejak? NOT by se mi hodilo…
Pokud by jsi chtel pomoci s vyvojem staci rict.
No… 5.9.2008 jsi mi to vehementně rozmlouval :-)
před 11 lety
- phx
- Člen | 652
To jsme si asi neporozumneli. Ja jsem chtel naznacit, ze by mohly vznikat nesmyslne konstrukce typu
SELECT * FROM tabulka WHERE sloupecek IN (klic='hodnota', klic2='hodnota2')
Osobne jsem to zatim resil pres DibiFluent, ale i tam to neni idealni.
před 11 lety
- David Grudl
- Nette Core | 6806
Nene, o takové konstrukce vůbec nešlo, šlo o ty NOT IN, LIKE, <, > atd, viz příklad výše. Např:
$where = array(
'neco% NOT IN'=>array(10, 20, 30)',
);
Ale jak říkám, nechal jsem si to rozmluvit :-)) a dnes se k té koncepci vracet nechci, už bych šel jinou cestou. Například:
$items = array(10, 20, 30);
$where = array(
array('[neco] NOT IN (%i)', $items),
);
před 11 lety
- David Grudl
- Nette Core | 6806
blacksun napsal(a):
K tomuto bych měl dotaz, jestli se dá nějak pracovat s polem podmínek, kde nejde o rovnost, ale větší menší apod., např. datum > 2008–10–10 AND datum < 2009–01–01.
Viz předchozí post, podpora by mohla vypadat třeba takto:
$where = array();
$where[] = array('datum > %d', '2008-10-10');
$where[] = array('datum < %d', '2009-01-01');
$where[] = ...;
dibi::query("SELECT * FROM posts WHERE %and", $where);
před 11 lety
- phx
- Člen | 652
Nad necim podobnym jsem take uvazoval, a chtel jsem si to rucne implementovat za pomoci %ex, ale nakonec jsem sel jinudy (DibiFluent).
Soucasne dibi tot nezvlada, ale bylo by to fajn, kdyby to umelo. V podstate staci udelat vyjimku aby to ciselne klice v poli vyhodnocovalo za pomoci %ex a nebralo to klic jako nazev sloupecku.
Pokud se v tom budes vrtat tak i tato uprava by mohla byt hezka ne?
$where = array(
'~neco'=>10,
);
před 11 lety
- David Grudl
- Nette Core | 6806
%ex
by šlo taky (přidám), v poslední revizi to už dnes lze
přes %sql
a číselné klíče v poli se tak vyhodnocují.
Vyzkoušej.
Přidávat '~neco'
nechci, je to hezké, ale někdo může
používat tento znak v názvu sloupce.
před 11 lety
- phx
- Člen | 652
SUPR SUPR SUPR:)
Vpodstate to vyresilo vsechny problemy v tomto vlaknu;) DIKY
před 11 lety
- krajaac
- Člen | 45
Mam jeste jeden dotaz,
jde v dibi spojovat v kauzuli WHERE podminky pomoci AND a OR zaroven?
Potreboval bych zkonstruovat neco v tomto stylu:
SELECT * FROM users WHERE sex = 'female' AND (chest >= 90 OR height >= 170)
vite nekdo jak na to? :)
Editoval krajaac (15. 1. 2009 20:04)
před 11 lety
- phx
- Člen | 652
Doporucil bych DibiFluent.
Jinak v array by to take mohlo jit nejak takto:
// pak vlozit jako parametr za %and
$where = array(
'sex'=>'female',
'(chest >= 90 OR height >= 170)'
);
Pisu to bez otestovani z hlavy. Snad to bude OK.
před 11 lety
- krajaac
- Člen | 45
phx napsal(a):
Doporucil bych DibiFluent.
Jinak v array by to take mohlo jit nejak takto:
// pak vlozit jako parametr za %and $where = array( 'sex'=>'female', '(chest >= 90 OR height >= 170)' );
Pisu to bez otestovani z hlavy. Snad to bude OK.
Diky za radu, jeste jsem to netestoval. Uvedomil jsem si, ze do dotazu cpat OR vubec neporebuju :D
Nicmene jsem zkousel zapis ve stylu:
<?php
$dibifluent
->select...->from...
->where(array('sex' => 'female'))
->where('%or', array('chest >= %i' => 90, 'chest >= %i' => 170) )
->limit...
?>
Ale nefungoval – vsechny prvky spojil ANDem.
před 11 lety
- David Grudl
- Nette Core | 6806
Ve výrazu
->where('%or', array('chest >= %i' => 90, 'chest >= %i' => 170) )
se chápe 'chest >= %i'
jako název klíče, tohle fungovat
nebude.
před 11 lety
- David Grudl
- Nette Core | 6806
David Grudl napsal(a):
Varianta s
%ex
také funguje. Příklady použití:// ekvivalentní zápisy: $pocet = 10; $where[] = array('pocet > %i', $pocet); $where['pocet%ex'] = array('> %i', $pocet);
Uvažuju nad tím, že to nebyl dobrý krok, lepší bude ponechat jen
$where[] = array('pocet > %i', $pocet)
a variantu
$where['pocet%ex'] = array('> %i', $pocet);
udělat
ekvivalentní s %sql
.