NDB – Where a spojení pomocí OR

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
MartinitCZ
Člen | 580
+
0
-

Jelikož jsem v doc nenalez „lehké“ řešení jako má dibi:

$color = $this->db->select('name')->from('color');

$is = array_map(function($s) {
	return array('slug = %s', $s);
}, (array) $slug);

$color->where('%or', $is);

return $color->fetchPairs();

zkusil jsem toto:

$likes = array_map(function ($c) {
	return ('color LIKE %' . $c . '%');
}, (array) $color);

$result->where(implode(' OR ', $likes));

Jenže NDB z toto udělá (přidá špatně `):

WHERE `color` LIKE %`blue`% OR `color` LIKE %`red`% OR `color` LIKE %`green`%

Jak tento dotaz vytvoři případně toto fixnout?

ViPEr*CZ*
Člen | 822
+
0
-

V NDB je potřeba namísto proměnných dát ? (otazníky).

$result->where("color LIKE ? OR color LIKE ? OR color LIKE ?" , array("%red%", "%blue%", "%green%"));

Počet prvků v druhém parametru se musí rovnat počtu otazníků v prvním parametru.

MartinitCZ
Člen | 580
+
0
-

@**ViPErCZ**: Díky, nicméně řešení nevypadá super.

$colors = array(); // množství n

$query = ''
foreach ($colors as $key => $color) {

	$colors[$key] = ('%' . $color . '%');
	$query .= 'color LIKE ? OR ';
}
$query = rtrim($query, ' OR ');

$result->where($query, $colors);

EDIT: No tak toto řešení nefunguje.
V $colors mám 4 položky. V $query mám 4x? a přes to to skončí na „There are more placeholders than passed parameters.“.

Editoval martinit (24. 4. 2014 12:52)

sKopheK
Člen | 207
+
0
-

Mě to takto funguje, jen jsem musel řešit případ, kdy při jediném otazníku nelze předat pole, ale jen jeden řetězec.

Jinak když už si nakousl „vzhled“ řešení, tak já bych byl raději pro

$condition = array();
foreach (...)
{
   ...
   $condition[] = 'color LIKE ?';
}
$query = join(' OR ', $condition);

Editoval sKopheK (24. 4. 2014 13:12)

MartinitCZ
Člen | 580
+
0
-

@**sKopheK**: To už je ± jedno. Ale použiji tvoje řešení, vypadá lépe.
Nicméně jsem došel k závaru, že problém je v ->having().
Pokud použiji where, jak je v příkladu, tak vše funguje. V mém případě s ->having() to ukazuje danou hlášku.

Editoval martinit (24. 4. 2014 13:24)

David Matějka
Moderator | 6445
+
0
-

@martinit: having asi nezvlada parametry jako array, zkus

call_user_func_array(array($result, 'having'), array_merge(array($query), $colors));
MartinitCZ
Člen | 580
+
0
-

@**matej21**: Toto už funguje, ale ......
Vzhledem k tomu, že nikoho, ani ničí práci, nechci urážet, tak to jen zhodnotím slovy „Zlaté dibi“.

Díky všem za pomoc ;)

matopeto
Člen | 395
+
0
-

lebo podla mna $colors nemoze byt pole, ale jednotlive parametre… Musis zavolat nieco ako:

<?php
$connection->queryArgs($result, $colors);
?>

pripadne

<?php

call_user_func_array(array($result, 'where'), array($query) + $colors);

?>

I ked mi obe pridu ako podivnosti :)

ViPEr*CZ*
Člen | 822
+
0
-

Tak to asi něco děláte špatně. Jinak syntaxe pro OR je kapku složitější. A pokud tam bude pár AND a ještě pár závorek, bude to ještě složitější :-D

martinit napsal(a):

@**ViPErCZ**: Díky, nicméně řešení nevypadá super.

$colors = array(); // množství n

$query = ''
foreach ($colors as $key => $color) {

	$colors[$key] = ('%' . $color . '%');
	$query .= 'color LIKE ? OR ';
}
$query = rtrim($query, ' OR ');

$result->where($query, $colors);

EDIT: No tak toto řešení nefunguje.
V $colors mám 4 položky. V $query mám 4x? a přes to to skončí na „There are more placeholders than passed parameters.“.

MartinitCZ
Člen | 580
+
0
-

@**ViPErCZ**: Já jsem tu trochu mátl. V příkladu požil where, ale pak mi došlo, že musím použít having … ;)
Nicméně kod od matej21 funguje super.
Akorát bych uvítal lepší „syntax“ a trochu intuitivnější řešení ⇒ přiblížit se dibi.
Ten kod od matej21 vych nikdy nevymyslel, a hlavně jsem nějaké call_user_func_array neměl potřebu použít, vlastně ho ani neznal.

David Matějka
Moderator | 6445
+
0
-

@martinit: jak by se tohle zapsalo v dibi?

MartinitCZ
Člen | 580
+
0
-

@**matej21**: V dibi např. takto (ověřeno):

	$is = array_map(function ($s) {
		return array('color LIKE %~like~', $s);
	}, (array) $color);

	$m->having('%or', $is);