Otazka ohladne Nette\Database\Connection
- ruller
- Člen | 29
Nette 2.0, php 5.3
Mám otázku
v presenteri volám:
//database z config.neon
$this->context->database->query('SELECT ...'); // funguje
$this->context->database->table('(SELECT zlozity...) AS mytable'); nefunguje
pri použití
use Nette\Database\Connection;
$database = new Connection('mysql:host=...;dbname=...', '...', '...');
$table=$database->table('(SELECT zlozity...) AS mytable');//tu funguje
môže mi niekto vysvetliť prečo to nefunguje, alebo čo robím zle?
config.neon database :
services:
database: @Nette\Database\Connection
ladenka hlási
Syntax error or access violation: 1103 Incorrect table name bla bla,
// ten select je rovnaký v oboch prípadoch
chcem dať connection a výber dát do modelu ale najskôr testujem
v presenteri.
ale nefunguje mi to :( čo robím zle?
Editoval ruller (7. 8. 2012 20:04)
- uestla
- Backer | 799
Mně osobně se nechtělo odpovídat, protože jsem prostě nevěděl, kde začít…
Používáš to špatně, možná jsi nedůkladně pročítal dokumentaci?
Každopádně $connection->query( ... )
slouží pro ruční
psaní SQL příkazů, kdežto $connection->table( ... )
slouží pro efektivní tahání dat z tabulek (i provázaných).
V dokumentaci se toho ale dočteš více a přesněji.
- ruller
- Člen | 29
nepoužívam to „špatně“. Poradil mi to Ot@s tu „:https://forum.nette.org/…-parametrami“
ide o to že nemôžem použit spájanie tabuliek nette way lebo na hostingu sa
nedá zvoliť InnoDB, iba MyISAM
Dokumentáciu mám naštudovanú, ale nefunguje vyberanie dát z
$this->context->database->table, kdežto pri pripojení v presenteri a
použití $database->table to funguje. to mi nejde do hlavy…
to query prvé bolo napísané len že query funguje, viem že to neslúži na
efektívne ťahanie dát
Editoval ruller (8. 8. 2012 14:19)
- ruller
- Člen | 29
prečo by som to robil ? :D len som to nahradil skutočným názvom :D och myslel som že si to domyslíte.. nevadí skúsim ešte raz
//prvy sposob v presenteri:
use Nette\Database\Connection;
$database = new Connection(...);
$this->template->inzeraty = $database->table("
(SELECT
t1.*,
t3.abc,
t3.cde,
t2.fd AS fd
FROM
(
SELECT *
FROM bc
) t1
INNER JOIN
(
SELECT *
FROM datum
) t2 ON t1.id = t2.id
INNER JOIN
(
SELECT *
FROM gf
) t3 ON t1.id = t3.id) AS mytable"); // funguje
//druhy sposob presenter :
//nedefinujem v hlavničke use Nette\Database\Connection;, používam database definované v config.neon
$this->context->database->table("
(SELECT
t1.*,
t3.abc,
t3.cde,
t2.fd AS fd
FROM
(
SELECT *
FROM bc
) t1
INNER JOIN
(
SELECT *
FROM datum
) t2 ON t1.id = t2.id
INNER JOIN
(
SELECT *
FROM gf
) t3 ON t1.id = t3.id) AS mytable"); //nefunguje
a v logu vypíše Syntax error or access violation: 1103 Incorrect table
name mytable
dúfam že už je jasné že kódy spúšťam…
Editoval ruller (8. 8. 2012 15:51)
- ruller
- Člen | 29
vvoody napsal(a):
MyISAM tomu nebrani (teda nejsom si isty ci myslime na to iste) :D skus napisat ako by si to riesil keby si mal InnoDB
nie nebráni, pretože to funguje, ale nefunguje to pri použití database
definované v config.neon
a keby som mal InnoDB riešil by som to cez model
$this->context->createNejakyModel()->where()
a tam by som spajal tabulky cudzimi klucmi… ale to nemôžem
- vvoody
- Člen | 910
no ja som mal na mysli nieco taketo (pisane z hlavy):
foreach($database->table("bc") as $bcRow){
// v pripade 1:1
// druhy parameter je stlpec v tabulke datum
$datumRow = $bcRow->ref('datum','id');
// v pripade 1:N
// druhy parameter je pomyselny FK v tabulke bc smerujuci na PK v tabulke gf
$gfTable = $bcRow->related('gf','id');
foreach($gfTable as $gfRow){
}
}
Neviem ci som trafil spravne tie vazby, ked tak si to prehod.
- vvoody
- Člen | 910
No praveze predpokladam ze prejdes uplne vsetky zaznami z tabulky bc (pripadne vyfiltrovane (where/limit/order) len na zaklade properties priamo v tejto tabulke) a potom pri kazdej iteracii vytahujes data z prepojenych tabuliek. Metoda ref vracia klasicky ActiveRow, to uz nieje Selecrion, preto som pomenoval tu premennu row :). Ale metoda related vracia Seleciton takze tam mozes aplikovat podmienky.
- ruller
- Člen | 29
aha cize ak to dobre chápem. dá sa použiť na odfiltrovanie napr. podľa id parametra
foreach($database->table("bc")->where('id',$this->id) as $bcRow){
//tu sa vytiahnu z tabulky datum data,len tie ktore maju rovnake id, teda $this->id?
$datumRow = $bcRow->ref('datum','id');
//tu sa da pouzit where ?
$gfTable = $bcRow->related('gf','id')->where();
foreach($gfTable as $gfRow){
}
}
chapem spravne ?
//EDIT
este stale by ma ale zaujimalo preco nefunguje cez this->context->database
pouzitie zloziteho selectu, ked podla mojho pohladu ide o rovnaky connection
ako pri pouziti \Nette\Connection
Editoval ruller (8. 8. 2012 18:14)
- vvoody
- Člen | 910
Ano. Ty to potrebujes vzdy len na jeden zaznam? Potom nepotrebujes foreach.
// vrati prvy najdeny riadok (ActiveRow) alebo NULL ked v tabulke neexistuje
$bcRow = $database->table("bc")->where('id',$this->id)->fetch();
// alebo ked id je PK
$bcRow = $database->table("bc")->get($this->id);
// get vracia priamo ActiveRow (alebo null)
Netusim preco ti ta query nefungovala nad database z contextu, ale pravdu povediac som netusil ze do funkcie table mozno taketo veci pisat. Ked uz je nevyhnutne si query napisat tak by bolo asi vhodnejsie pouzit funkciu query. V prvom poste pises ze ta ti funguje. Tu nemozes pouzit?
- ruller
- Člen | 29
nie nemôžem, pretože query má dynamický počet where, podľa zadaných možností z formulára, a pri query musíš vedieť koľko tam je parametrov
//mozes mat takto pripraveny query, ale ked pribudne parameter tamto musel by si mal vela ifov ktore vyberu spravne query s parametrami...
$query=$database->query("SELECT id,nieco,tamto FROM table WHERE id=? and nieco=?",$id,$nieco);
a preto musim pouzit $database->table()->where().. to sa da dynamicky pridavat
a foreach asi nebudem potrebovat pre prvy vyber, ale pre ostatné tabuľky kde je 1:N uvidím ešte sa s tým pohrám, každopádne Dík :)