Otazka ohladne Nette\Database\Connection

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

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)

ruller
Člen | 29
+
0
-

nikto? je to bug? alebo je to primitivne ze nikto neodpoveda ? :)))

uestla
Backer | 799
+
0
-

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
+
0
-

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)

uestla
Backer | 799
+
0
-

Právě jsem dojedl svůj klobouk – omlouvám se. O tomto jsem nevěděl.

Ta hláška, kterou jsi sem napsal, dokazuje, že nám tu ukazuješ kódy, které pak nespouštíš – evidentně se snažíš přistoupit k tabulce „bla bla“.

vvoody
Člen | 910
+
0
-

MyISAM tomu nebrani (teda nejsom si isty ci myslime na to iste) :D skus napisat ako by si to riesil keby si mal InnoDB

ruller
Člen | 29
+
0
-

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
+
0
-

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
+
0
-

Ukaz ako by si ich spajal keby tam ten cudzi kluc bol. Ja si stale myslim ze tie kluce tam niesu nevyhnutne. Ale stale si nejsom isty ci myslime na to iste :) tak preto chcem vidiet konkretny kod.

ruller
Člen | 29
+
0
-

nejako takto ?

$database = new Connection(...);
$database->table("bc")->where("datum.id = ?", 1)->where ... atd

asi tak nejako by to bolo, spájanie cez id ale potrebujem v mojom query

Editoval ruller (8. 8. 2012 16:11)

vvoody
Člen | 910
+
0
-

tie 3 tabulky maju medzi sebou vzdy vazbu 1:1?

ruller
Člen | 29
+
0
-

maju 1:1 , 2 tabulky, tretia je 1:N a mal by tam byt left join lebo niekedy nie je, to musim opravit, ale myslim ze je jedno aky vztah tam je. skusal som spajat len 2 tabulky a aj tak to pise chybu

vvoody
Člen | 910
+
0
-

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.

ruller
Člen | 29
+
0
-

toto vidím prvý krát, môžeš mi vysvetliť čo to robí, a ako sa dá použiť pri tom podmienka where ? vnútri foreach? $datumRow = $bcRow->ref(‚datum‘,‚id‘)->where(‚id‘,5); ← takto ?

vvoody
Člen | 910
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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 :)