Nefunkční cizí klíče v nette\database
- konva
- Člen | 88
Ahoj,
nefunguje mi dotazování na propojené tabulky.
Mám takovýto dotaz
$this->database->table('uzivatelRole')->select('uzivatelRole.*, cisPol.*')->where('urUzivatelId', $row->uzId)->fetchPairs('cpId', 'cpKod')
a v databázi definovaný cizí klíč
alter table uzivatelRole add constraint FK_Reference_97 foreign key (urUzivatelId) references uzivatel (uzId) on delete restrict on update restrict;
ale dotaz píše chybu
No reference found for $uzivatelRole->cisPol
Kde delam chybu?
- konva
- Člen | 88
ted uplne nerozumim. Odkazuju se tabulkou UzivatelRole na tabulku CisPol, tedy mam cizi klic na tabulce UzivatelRole. Proc bych mel mit nejaky cizi klic na tabulce CisPol?
Pro poradek. Na tabulce CisPol mam nastaveny cizi klic na
cisPol.cpRodicId -> cisPol.cpId
zajistujici hierarchii polozek
a klic
cisPol.cpCisId -> cis.csId
odkazujici na tabulku s definici ceselniku
- David Matějka
- Moderator | 6445
ukaz prosim celou strukturu db (respektive tech dulezitych tabulek), ja se v tech zkratkach nevyznam.. (to pouzivas nejaky nahodny generovani nazvu? :) )
- konva
- Člen | 88
Takovy paradni nazby si tvorim sam :)
Zjednodusena struktura je nasledujici. Tabulky:
cisCis – tabulka s definici ciselniku (napr. role, kategorie, zeme, …)
cisPol – polozky ciselniku
uzivatel – tabulka uzivatelů
uzivatelRole – tabulka s vazbou na uzivatele a jeho role
create table cisCis
(
ccId int not null auto_increment,
ccRodicId int,
ccKod varchar(40),
ccNazev varchar(100),
primary key (ccId)
);
alter table cisCis add constraint FK_Reference_1 foreign key (ccRodicId) references cisCis (ccId) on delete restrict on update restrict;
create table cisPol
(
cpId int not null auto_increment,
cpCisCisId int,
cpRodicId int,
cpKod varchar(40),
cpNazev varchar(200),
primary key (cpId)
);
alter table cisPol add constraint FK_Reference_2 foreign key (cpRodicId) references cisPol (cpId) on delete restrict on update restrict;
alter table cisPol add constraint FK_Reference_3 foreign key (cpCisCisId) references cisCis (ccId) on delete restrict on update restrict;
create table uzivatel
(
uzId int not null,
uzJmeno varchar(200),
primary key (uzId)
);
create table uzivatelRole
(
urRoleId int not null,
urUzivatelId int not null,
primary key (urRoleId, urUzivatelId)
);
alter table uzivatelRole add constraint FK_Reference_16 foreign key (urRoleId) references cisPol (cpId) on delete restrict on update restrict;
alter table uzivatelRole add constraint FK_Reference_97 foreign key (urUzivatelId) references uzivatel (uzId) on delete restrict on update restrict;
- David Matějka
- Moderator | 6445
ok..
pro „to one“ smer neni dulezity nazev tabulky, ale nazev sloupce s cizim
klicem, nazev cilove tabulky je dulezity pro „to many“ smer.
takze v
->select('uzivatelRole.*, cisPol.*')
nahrad cisPol za nazev sloupce (respektive jeho cast) v tabulce uzivatelRole:
->select('uzivatelRole.*, uzRole.*')
- konva
- Člen | 88
Díky, funguje to, ale úplně tomu nerozumím. Proč je tam ta hvězdička
„uzRole.*“? Proč nemůžu napsat celý název sloupce?
....................
Uz chapu, ze ta chvezdicka znaci sloupce, ale moc mi nejde na rozum jaktoze mi
to funguje kdyz napisu
"uzRole.*"
\-- i kdyz napicu
/--php
"uzRoleId.*"
\--
/--php
"uzRo.*"
Editoval konva (7. 2. 2014 13:41)
- David Matějka
- Moderator | 6445
je to hlavne kvuli tomu, aby to fungovalo v activerow. budes mit activerow s uzivatelRole a budes chtit tu roli, kdybys pouzil
$uzivatelRole->uzRoleId
tak by ti to vratilo obsah sloupecku, pouzijes tedy
$uzivatelRole->uzRole
a ono to zjisti, ze neexistuje takovy sloupecek a tak to hleda, zda existuje sloupecek s FK, ktery obsahuje tento retezec
- konva
- Člen | 88
OK, díky.
Ještě bych tě využil na dvě otázky, protože s tím docela bojuju.
Navážu na ty tabulky co jsem psal výše. Mám tam ještě
mainId – tabulka, ktera slouzi k vytvareni unikagnich ID pro vetsinu
obsahu
polClanek – clanky
polClanekSerial – ciselnik serialu
obsStitekSlova – ciselnik stitku (tagu)
obsStitekVazba – vazba clanku (resp ruzneho obsahu s mainId) a stitku
create table mainId
(
miId int not null auto_increment,
primary key (miId)
);
create table polClanek
(
ckId int not null,
ckUzivatelId int,
ckClanekKategorieId int comment,
ckSerialId int,
ckStavId int,
ckNadpis varchar(200),
primary key (ckId)
);
alter table polClanek add constraint FK_Reference_145 foreign key (ckSerialId) references polClanekSerial (srId) on delete restrict on update restrict;
alter table polClanek add constraint FK_Reference_45 foreign key (ckId) references mainId (miId) on delete restrict on update restrict;
alter table polClanek add constraint FK_Reference_51 foreign key (ckClanekKategorieId) references cisPol (cpId) on delete restrict on update restrict;
alter table polClanek add constraint FK_Reference_49 foreign key (ckStavId) references cisPol (cpId) on delete restrict on update restrict;
create table polClanekSerial
(
srId int not null,
srNazev varchar(200),
primary key (srId)
);
create table obsStitekSlova
(
slId int not null auto_increment,
slSlovo varchar(100),
primary key (slId)
);
create table obsStitekVazba
(
svSlovoId int not null,
svMainId int not null,
primary key (svSlovoId, svMainId)
);
alter table obsStitekVazba add constraint FK_Reference_61 foreign key (svSlovoId) references obsStitekSlova (slId) on delete restrict on update restrict;
alter table obsStitekVazba add constraint FK_Reference_62 foreign key (svMainId) references mainId (miId) on delete restrict on update restrict;
A chtěl bych při výpisu článků dostat např. název seriálu, ale toto mi nefunguje
{$clanek->polClanekSerial->srNazev}
Tohle už ale jo
{$clanek->ref('polClanekSerial', 'ckSerialId')->srNazev}
Nebo nevím jak si mohu vypsat jen ty články které mají vazbu na určitý
štítek (tag), je to vazba
polClanek ← obsStitekVazba → obsStitekSlova
Moc díky
- David Matějka
- Moderator | 6445
diky mainId tabulce je to hodne tezky, v NDBT snad nemozny…
vykasli se na tu tabulku mainId, akorat si komplikujes zivot..
- konva
- Člen | 88
No proc ne, ale tak poradte jak vyresit kdyz mam napr. tabulku
„komentare“ a do ni ukladam zaznamy diskuse. Komentare jsou ale pod clanky,
ale i treba pod obrazkam v galerii. A prijde mi zbytecne mit dve tabulky
s komentari, jednu pro galerii a druhou pro clanky. Potrebuji mit tedy unikatni
ID. A navic ty komentare musi mit cizi klic na tabulku kde jsou vsechny ID.
Rad to predelam, jen me nenapada lepsi reseni.
- konva
- Člen | 88
Mimochodem i kdybych tam nemel tu mainId tabulku, tak porad se snazim prijit na to jak napsat dotaz ktery by mi vratil jen clanky, ktere maji urcity tag.
Tedy zapis v SQL by vypadal takto
select * from polClanek
join obsStitekVazba on ckId=svMainId
join obsStitekSlova on svSlovoId=slId
where slSlovo='krajina'
Momentalne mam cizi klice pres tu MainId, ale nevim jak to zapsat i kdybych
mel ty tabulky propojene mezi sebou.
Diky
- David Matějka
- Moderator | 6445
zkus:
$context->table('polClanek')
->where('ckId:obsStitekVazba.svSlovo.slSlovo', 'krajina');