chyba při generování dotazu?

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

Nette verze 2.1 devel z 30.7.2012, PostgreSQL. Mám přibližně takovýto kód (čekal bych chybu mezi židlí a klávesnicí, ale nedohledal jsem ji):

<?php
...
$this->koefs = $this->context->koef->getKoefs($this->rok, $this->lvrec->obec_id);
foreach ($cosi as $this->record) {
	$this->sazba = $this->sazebnik->getSazba($this->rok, $this->record->druhnem->konverze);
	if       ($this->sazba->koef10) { // koef 10
		$this->koef   = $this->koefs->where('paragraf',10)
			->where('druh',$this->record->druhnem->konverze)
			->limit(1)->fetch();
		$this->koef10 = ($this->koef) ? $this->koef->koeficient : 10;
		$this->kontrola[$this->record->id.'k10'] = $this->koef11;
	} elseif ($this->sazba->koef11) { // koef 11
		$this->koef   = $this->koefs
			->where(array('paragraf'=>11, 'druh'=>$this->record->druhnem->konverze))
			->limit(1)->fetch();
		$this->koef11 = ($this->koef) ? $this->koef->koeficient : 10;
		$this->kontrola[$this->record->id.'k11'] = $this->koefs;
	}
	if       ($this->sazba->koef12) { // koef 12
		$this->koef   = $this->koefs->where('paragraf',12)->limit(1)->fetch(); !!!
		$this->koef12 = ($this->koef) ? $this->koef->koeficient : 10;
		$this->kontrola[$this->record->id.'k12'] = $this->koefs;
	}
}
...
$this->template->kontrola = $this->kontrola;
?>

Model vypadá takto:

<?php
public function getKoefs ($rok, $obec) {
	return $this->connection->table('koef')->where(array('rok_id'=>$rok, 'obec_id'=>$obec));
}
?>

Tu kontrolu dumpuji v šabloně. Pokud zakomentuji řádek označený !!!, tvoří se v bloku 1. podmínky (pro koef10 a koef11 ) očekávané dotazy typu (dotazy pro koef12 samozřejmě nejsou):

SELECT * FROM "koef" WHERE ("rok_id" = ?) AND ("obec_id" = ?) AND ("paragraf" = ?) LIMIT 1

Pokud řádek zakomentovaný není, je tedy funkční dotaz pro koef12 (v bloku nezávislém na předchozích koef10 a koef11), tvoří se pro koef12 očekávaný dotaz (jako výše), ale dotaz pro koef10 a koef11 vypadá:

SELECT * FROM "koef"
WHERE ("rok_id" = ?) AND ("obec_id" = ?) AND ("paragraf" = ?) AND ("paragraf" = ?) AND ("druh" = ?)
LIMIT 1

Tedy podmínka pro paragraf je tam 2× a dosazují se obě hodnoty – 11 i 12 (testuji zatím pouze tu větev 11)

Editoval jik (4. 9. 2012 18:48)

jtousek
Člen | 951
+
0
-

Tipnul bych, že

if       ($this->sazba->koef12) {

má být:

elseif       ($this->sazba->koef12) {
jik
Člen | 149
+
0
-

Právě, že ne. Podmínky jsou 2:
první buď 10 nebo 11 nebo nic
druhá buď 12 nebo nic

jtousek
Člen | 951
+
0
-

V tom případě nevím čemu se divíš.

//přidá AND ("paragraf" = 11)
$this->koef   = $this->koefs
                        ->where(array('paragraf'=>11, 'druh'=>$this->record->druhnem->konverze))
...
//přidá AND ("paragraf" = 12)
$this->koef   = $this->koefs->where('paragraf',12)->limit(1)->fetch(); !!!
jik
Člen | 149
+
0
-

Divím se tomu, že uvnitř podmínek naplňuji proměnné $koef10, $koef11 $koef12 – tedy předpokládám, že v podmínce 10/11 $koef11 již nebude zasažen podmínkou 12.

jtousek
Člen | 951
+
0
-

Proměnná $this->koefs je objekt třídy \Nette\Database\Table\Selection.

Nad ním voláš ->where(array('paragraf'=>11, 'druh'=>$this->record->druhnem->konverze)), což do něj přidá tu první podmínku. Pak voláš fetch. Ta podmínka v tom objektu ale samozřejmě už zůstane!!

O kousek dál nad stejným objektem voláš ->where('paragraf',12), což přidá tu druhou podmínku.

Řešení:

$this->koef   = $this->koefs
                       ->where(array('paragraf'=>11, 'druh'=>$this->record->druhnem->konverze))
                       ->limit(1)->fetch();

=>

$selection   = clone $this->koefs;
$this->koef = $selection->where(array('paragraf'=>11, 'druh'=>$this->record->druhnem->konverze))
                       ->limit(1)->fetch();

Poznámka mimo: mám pocit že máš dost špatné pojmenování proměnných. Podle názvu se naprosto neorientuju, co která proměnná má obsahovat.

jik
Člen | 149
+
0
-

Děkuji za vysvětlení.