Kezdőoldal » Számítástechnika » Weblapkészítés » Mi a probléma ezzel az sql...

Mi a probléma ezzel az sql lekérdezéssel?

Figyelt kérdés

Készítek egy cms rendszert, ami max 3 szintű megnüvel dolgozik majd, azokat elkészíti, és feltölti tartalommal.


A menüpontok táblái így néznek ki:


első tábla:

id->menuname->url


a többi:

id->menuname->url->relation



A menuname az az ékezetes menünév, az url az nyilván az ékezet nélküli, a relation pedig a szülőmenühöz való kapcsolódás.


Tehát ha van egy olyan menürendszerünk, hogy:


szolgáltatások->weboldal->céges weboldal

akkor az első tábla értékei a következők lesznek:


menuname = szolgáltatások

url = szolgaltatasok


második tábla:


menuname = honlapkészítés

url = honlapkeszites

relation = szolgaltatasok


stb...


Törléskor szeretnék inner joint használni, hogy lehúzzam a kapcsolódások url-jét, és aszerint töröljem ki az almenüket is, ha a főmenüt kitörlöm.


Ez lenne az sql kód:


SELECT 'menu_level1.url' AS 'url1', 'menu_level2.url' AS 'url2' FROM `menu_level1` INNER JOIN `menu_level2` ON 'menu_level1.url' = 'menu_level2.relation'


mondjuk két szintű menü esetében.


A gond csak az, hogy hiába van a menu_level1-ben is szolgaltatasok url és a menu_level2-ben is szolgaltatasok relation, üres értéket ad vissza az sql query.


Mit nem értek? A számításaim szerint ennek ebben a formában jónak kéne lennie. Valami ötlet?



2018. jan. 6. 15:24
 1/6 anonim ***** válasza:
Szerintem inkább az a kérdés, mi a baj ezzel az adatbázissal. Minden menünek külön tábla? Innentől jó már nem lehet.
2018. jan. 6. 18:10
Hasznos számodra ez a válasz?
 2/6 2*Sü ***** válasza:
100%

A probléma az szimpla idézőjel és a backtick/backquote karakterek keveredéséből van.

` ≠ '


Vagy nem használsz backtick karaktereket, és akkor így néz ki helyesen:

SELECT menu_level1.url AS url1, menu_level2.url AS url2 FROM menu_level1 INNER JOIN menu_level2 ON menu_level1.url = menu_level2.relation

(Persze ebben az esetben nem használhatsz táblanévnek, mezőnévnek foglalt kulcsszót, nem lehet benne szóköz, stb…)


Vagy a backtick/backquote karaktert használod a tábla és mezőneveknél, és akkor így néz ki a dolog:

SELECT `menu_level1`.`url` AS `url1`, `menu_level2`.`url` AS `url2` FROM `menu_level1` INNER JOIN `menu_level2` ON `menu_level1`.`url` = `menu_level2`.`relation`

(Itt a tábla és mezőneveket külön-külön kell backquote jelekkel határolni.)


A szimpla idézőjel szöveghatároló karakter. Mit csinál a te lekérésed? Végigveszi a menu_level1 és a menu_level2 tábla összes sorának kombinációját, és az eredmény sok menüpont esetén egy sok soros tábla lesz, ahol minden sorban az url1 értéke egy szöveg, méghozzá a „menu_level1.url” szöveg. Ezekből a sorokból csak azt tartja meg, ahol a „menu_level1.url” – mint string – egyenlő a „menu_level2.relation”-nal – mint stringgel – de mivel a két string nem lesz azonos soha, egyetlen sor esetén sem, ezért kapsz vissza egy üres táblát.


Hogy jobban megértsd, mi a gond, próbáld ki ezt:


SELECT 'menu_level1.url' AS 'url1' FROM menu_level1


~ ~ ~


De ahogy az első utalt rá, maga az adatbázis felépítése nem éppen „elegáns”, nem felel meg az adatbázisok felépítésétől általában elvárt szabályoknak. Mert hiszen a menu_level1 és a menu_level2 ugyanolyan jellegű adatokat tartalmaz. Ha most kitalálja valaki, hogy legyen egy tooltip szöveg minden fő- és almenüponthoz, akkor két táblát is kell módosítanod. Az egész megoldható egyetlen táblával:


CREATE TABLE menu (

id INT NOT NULL AUTO_INCREMENT,

url VARCHAR(255) NOT NULL,

menuname VARCHAR(255) NOT NULL,

parent INT NULL DEFAULT NULL,

PRIMARY KEY (id));


Vagy ha nem akarod, hogy egy fő- és egy almenünek, vagy két fő-, vagy két almenünek ugyanaz legyen véletlenül az url-je, akkor:


CREATE TABLE menu (

id INT NOT NULL AUTO_INCREMENT,

url VARCHAR(255) NOT NULL,

menuname VARCHAR(255) NOT NULL,

parent INT NULL DEFAULT NULL,

PRIMARY KEY (id),

UNIQUE INDEX url_idx (url ASC));


Ebben az esetben a példád így néz ki:


id ; url ; menuname ; parent

1 ; szolgaltatasok ; Szolgáltatások ; NULL

2 ; honlapkeszites ; Honlapkészítés ; 1


A GYK menüje meg így:

26 ; allatok ; Állatok ; NULL

27 ; allatok_allatvedelem ; Állatvédelem ; 26

28 ; allatok__halak-akvarisztika ; Halak, akvarisztika ; 26

328; szamitastechnika ; Számítástechnika ; NULL

329; szamitastechnika__biztonsag ; Biztonság ; 328

330 ; szamitastechnika__hardverek ; Hardverek ; 328


További előnye a dolognak, hogy az adatbázis átalakítása nélkül lehet egy harmadik, negyedik, akárhányadik szintet is tárolni így.


~ ~ ~


Le akarod kérni a főmenü elemeit?

SELECT * FROM menu WHERE parent IS NULL;


Le akarod a 328-as azonosítójú (Számítástechnika) menü összes almenüpontját?

SELECT * FROM menu WHERE parent=328;


Törölni akarod a Hardverek menüpontot?

DELETE FROM menu WHERE url='szamitastechnika_hardverek';

vagy

DELETE FROM menu WHERE id=330;


Törölni akarod a Számítástechnika menüt az összes almenüpontjával együtt?

DELETE FROM menu WHERE (id=328) OR (parent=328);


~ ~ ~


Metakritika: Nyugtass meg, hogy nem akarsz így kezdő SQL ismeretekkel és gyakorlattal honlaptervezésbe fogni.

2018. jan. 6. 19:16
Hasznos számodra ez a válasz?
 3/6 A kérdező kommentje:

Tényleg nem kötekedni akarok, de ezt őszintén szólva nem értem:

„menu_level1.url” – mint string – egyenlő a „menu_level2.relation”-nal

de mivel a két string nem lesz azonos soha, egyetlen sor esetén sem, ezért kapsz vissza egy üres táblát. "


Miért nem lesz egyenlő soha a két string? Biztos így van, mert nulla sort kapok vissza, de amennyiben a relation is 'szolgaltatasok' valamint az url is 'szolgaltatasok' akkor mi az oka annak, hogy ez a kettő sosem lesz egyenlő?

2018. jan. 6. 23:30
 4/6 2*Sü ***** válasza:
100%

Azért, mert ez:

menu_level1.url = menu_level2.relation

vagy ez:

`menu_level1`.`url` = `menu_level2`.`relation`

ezek a menu_level1 tábla adott sorának url mezőjét hasonlítják össze a menu_level2 tábla relation mezőjével, és itt mindegy is, hogy ezek a mezők most stringet, számot, dátumot, vagy mit tartalmaznak. Ha történetesen mindkét tábla adott sorának adott mezeje az, hogy 'szolgaltatasok', akkor a kifejezés igaz lesz.


Míg ez:

'menu_level1.url' = 'menu_level2.relation'

(így idézőjelek közé téve) semmiféle tábla semmiféle mezőjét nem veszi, hanem ez két string, mindkét string 'm' karakterrel kezdődik, 'e' karakterrel folytatódik, viszont a bal oldali egy 'l' karakterre, a jobb oldali egy 'n' karakterre végződik. Tulajdonképpen ezt jelenti:

'menu_'+'level'+'1.ur'+'l' = 'me'+'nu_le'+'ve'+'l2.re'+'lati'+'on'

Ez meg soha az életben nem lesz igaz, a 'menu_level1.url' egy 15 karakterből álló string, míg a 'menu_level2.relation' egy 20 karakterbő álló string.


Tulajdonképpen olyan, mintha azt írtad volna, hogy:

… INNER JOIN menu_level2 ON 'alma' = 'körte'

vagy:

… INNER JOIN menu_level2 ON 4 = 5

2018. jan. 7. 02:32
Hasznos számodra ez a válasz?
 5/6 A kérdező kommentje:

Ja így már értem, köszönöm szépen! :)

Az a helyzet, hogy pont ezért kezdtem el fejleszteni az sql tudásomat, de kettő, elvileg felsőoktatási célra szánt könyvben nem volt leírva a backquote és a single quote közötti különbség. A w3school vonatkozó oldalán pedig quotation markok nélkül vannak a példák. Amúgy valszeg php-val működött volna a kód, de a phpmyadmin felületén próbáltam így lekérdezni.


De végülis egy netes tutoriálban megtaláltam a választ.

2018. jan. 7. 08:48
 6/6 anonim ***** válasza:
A backquote jelet kezdőként el is felejtheted. Akkor kell, ha egy mezőnévben szokatlan karakterek vannak, de amíg angol alfanumerikus karaktereket használsz, simán elhagyhatóak. Az olyan programok, mint pl. a phpmyadmin maguktól kiteszik mindig a biztonság kedvéért.
2018. jan. 7. 08:57
Hasznos számodra ez a válasz?

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!