Da li je moguće staviti klauzulu LIMIT x, y u stornoj proceduri gde su x i y parametri koji se prosleđuju prilikom poziva procedure? Nešto pokušavam ali ne ide, javlja neku grešku.
LIMIT u proceduri - da li je moguće?
Zaključano
Zakačeno
jeste samo nema mnogo smisla
Code:
mysql> drop procedure if exists y;
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> create procedure y(IN a int, IN b int)
-> begin
-> set @q := CONCAT('select id from t4 limit ', a, ',', b);
-> prepare stmt from @q;
-> execute stmt;
-> end//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call y(0,100);
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+
10 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> call y(2,3);
+----+
| id |
+----+
| 3 |
| 4 |
| 5 |
+----+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> drop procedure if exists y;
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter //
mysql> create procedure y(IN a int, IN b int)
-> begin
-> set @q := CONCAT('select id from t4 limit ', a, ',', b);
-> prepare stmt from @q;
-> execute stmt;
-> end//
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call y(0,100);
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
+----+
10 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> call y(2,3);
+----+
| id |
+----+
| 3 |
| 4 |
| 5 |
+----+
3 rows in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql>
Potpis
Probao sam ovaj upit i radi sa ovim prepared statement. Međutim ne mogu da se snađem oko navodnika i duplih navodnika u svojoj malo većoj proceduri. Pretpostavljam da treba da se koriste dupli i obični navodnici ali ne znam koji treba da stavljam unutar kojeg. Pokušavao sam nešto ali nije htela procedura da radi. Problem mi je deo iza where uslova. Ako može neko da mi pokaže kako da odradim samo ovaj deo: where ((n.ime like concat(pime,'%') or pime is null or pime='')
Krenuo sam tako što sam stavio set @q:=concat("select n.ime as ime, n.prezime as ....
ali nešto nije htelo.
Krenuo sam tako što sam stavio set @q:=concat("select n.ime as ime, n.prezime as ....
ali nešto nije htelo.
Code (sql):
DELIMITER $$
CREATE DEFINER=`pravni`@`localhost` PROCEDURE `SP_PRETRAZI_NASTAVNIKA`(IN pime VARCHAR(25), IN pprezime VARCHAR(35), IN pzvanje VARCHAR(25), IN pkatedra VARCHAR(40), IN brojredova INT, IN poffset INT)
BEGIN
SET names utf8;
SELECT n.ime AS ime, n.prezime AS prezime, z.naziv AS zvanje, k.naziv AS katedra, f.naziv AS funkcija, ra.naziv AS radnoangazovanje
FROM ((((((((NASTAVNIK N LEFT JOIN NASTAVNIK_ZVANJE NZ ON N.NastavnikID=NZ.NastavnikID) LEFT JOIN
ZVANJE Z ON z.zvanjeId=nz.zvanjeid) LEFT JOIN
KATEDRA K ON K.Katedraid=N.KatedraID) LEFT JOIN
NASTAVNIK_RADNO_ANGAZOVANJE NRA ON NRA.NastavnikID=N.NastavnikID) LEFT JOIN
RADNO_ANGAZOVANJE RA ON RA.TipRadnogAngazovanjaID=NRA.TipRadnogAngazovanjaID) LEFT JOIN
NASTAVNIK_FUNKCIJA NF ON NF.NastavnikID=N.NastavnikID) LEFT JOIN
FUNKCIJA F ON F.FunkcijaID=NF.FunkcijaID))
WHERE ((n.ime LIKE concat(pime,'%') OR pime IS NULL OR pime='') AND (n.prezime LIKE concat(pprezime,'%') OR pprezime IS NULL OR pprezime='') AND (z.naziv LIKE concat(pzvanje,'%') OR pzvanje IS NULL OR pzvanje='') AND (k.naziv LIKE concat(pkatedra,'%') OR pkatedra IS NULL OR pkatedra=''))
;
END
DELIMITER $$
CREATE DEFINER=`pravni`@`localhost` PROCEDURE `SP_PRETRAZI_NASTAVNIKA`(IN pime VARCHAR(25), IN pprezime VARCHAR(35), IN pzvanje VARCHAR(25), IN pkatedra VARCHAR(40), IN brojredova INT, IN poffset INT)
BEGIN
SET names utf8;
SELECT n.ime AS ime, n.prezime AS prezime, z.naziv AS zvanje, k.naziv AS katedra, f.naziv AS funkcija, ra.naziv AS radnoangazovanje
FROM ((((((((NASTAVNIK N LEFT JOIN NASTAVNIK_ZVANJE NZ ON N.NastavnikID=NZ.NastavnikID) LEFT JOIN
ZVANJE Z ON z.zvanjeId=nz.zvanjeid) LEFT JOIN
KATEDRA K ON K.Katedraid=N.KatedraID) LEFT JOIN
NASTAVNIK_RADNO_ANGAZOVANJE NRA ON NRA.NastavnikID=N.NastavnikID) LEFT JOIN
RADNO_ANGAZOVANJE RA ON RA.TipRadnogAngazovanjaID=NRA.TipRadnogAngazovanjaID) LEFT JOIN
NASTAVNIK_FUNKCIJA NF ON NF.NastavnikID=N.NastavnikID) LEFT JOIN
FUNKCIJA F ON F.FunkcijaID=NF.FunkcijaID))
WHERE ((n.ime LIKE concat(pime,'%') OR pime IS NULL OR pime='') AND (n.prezime LIKE concat(pprezime,'%') OR pprezime IS NULL OR pprezime='') AND (z.naziv LIKE concat(pzvanje,'%') OR pzvanje IS NULL OR pzvanje='') AND (k.naziv LIKE concat(pkatedra,'%') OR pkatedra IS NULL OR pkatedra=''))
;
END
Potpis
Code:
drop procedure if exists `SP_PRETRAZI_NASTAVNIKA`;
DELIMITER //
CREATE DEFINER=`pravni`@`localhost` PROCEDURE `SP_PRETRAZI_NASTAVNIKA`(
IN pime varchar(25), IN pprezime varchar(35), IN pzvanje varchar(25),
IN pkatedra varchar(40), IN brojredova int, IN poffset int)
BEGIN
SET names utf8; -- ?!?!?!?!
set @q := CONCAT("
SELECT n.ime AS ime, n.prezime AS prezime, z.naziv AS zvanje, k.naziv AS katedra, f.naziv AS funkcija, ra.naziv AS radnoangazovanje
FROM ((((((((NASTAVNIK N LEFT JOIN NASTAVNIK_ZVANJE NZ ON N.NastavnikID=NZ.NastavnikID) LEFT JOIN
ZVANJE Z ON z.zvanjeId=nz.zvanjeid) LEFT JOIN
KATEDRA K ON K.Katedraid=N.KatedraID) LEFT JOIN
NASTAVNIK_RADNO_ANGAZOVANJE NRA ON NRA.NastavnikID=N.NastavnikID) LEFT JOIN
RADNO_ANGAZOVANJE RA ON RA.TipRadnogAngazovanjaID=NRA.TipRadnogAngazovanjaID) LEFT JOIN
NASTAVNIK_FUNKCIJA NF ON NF.NastavnikID=N.NastavnikID) LEFT JOIN
FUNKCIJA F ON F.FunkcijaID=NF.FunkcijaID))
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='') AND (n.prezime LIKE '",pprezime,"%') OR pprezime IS NULL OR pprezime='')
AND (z.naziv LIKE '",pzvanje,"%') OR pzvanje IS NULL OR pzvanje='') AND (k.naziv LIKE '",pkatedra,"%') OR pkatedra IS NULL OR pkatedra=''))");
prepare stmt from @q;
execute stmt;
END //
delimiter ;
drop procedure if exists `SP_PRETRAZI_NASTAVNIKA`;
DELIMITER //
CREATE DEFINER=`pravni`@`localhost` PROCEDURE `SP_PRETRAZI_NASTAVNIKA`(
IN pime varchar(25), IN pprezime varchar(35), IN pzvanje varchar(25),
IN pkatedra varchar(40), IN brojredova int, IN poffset int)
BEGIN
SET names utf8; -- ?!?!?!?!
set @q := CONCAT("
SELECT n.ime AS ime, n.prezime AS prezime, z.naziv AS zvanje, k.naziv AS katedra, f.naziv AS funkcija, ra.naziv AS radnoangazovanje
FROM ((((((((NASTAVNIK N LEFT JOIN NASTAVNIK_ZVANJE NZ ON N.NastavnikID=NZ.NastavnikID) LEFT JOIN
ZVANJE Z ON z.zvanjeId=nz.zvanjeid) LEFT JOIN
KATEDRA K ON K.Katedraid=N.KatedraID) LEFT JOIN
NASTAVNIK_RADNO_ANGAZOVANJE NRA ON NRA.NastavnikID=N.NastavnikID) LEFT JOIN
RADNO_ANGAZOVANJE RA ON RA.TipRadnogAngazovanjaID=NRA.TipRadnogAngazovanjaID) LEFT JOIN
NASTAVNIK_FUNKCIJA NF ON NF.NastavnikID=N.NastavnikID) LEFT JOIN
FUNKCIJA F ON F.FunkcijaID=NF.FunkcijaID))
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='') AND (n.prezime LIKE '",pprezime,"%') OR pprezime IS NULL OR pprezime='')
AND (z.naziv LIKE '",pzvanje,"%') OR pzvanje IS NULL OR pzvanje='') AND (k.naziv LIKE '",pkatedra,"%') OR pkatedra IS NULL OR pkatedra=''))");
prepare stmt from @q;
execute stmt;
END //
delimiter ;
jedan hint,
((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='')
ovo ce osigurati da ovaj upit nikada ne koristi index, dakle radice full table scan - spooro... LIKE je operand koji treba izbegavati gde god je moguce
Potpis
CALL SP_PRETRAZI_NASTAVNIKA2("","","","",2,2)
izbacuje mi poruku:
Error Code: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')
AND (z.naziv LIKE '%') OR pzvanje IS NULL OR pzvanje='') AND (k.naziv LIK' at line 9
izbacuje mi poruku:
Error Code: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')
AND (z.naziv LIKE '%') OR pzvanje IS NULL OR pzvanje='') AND (k.naziv LIK' at line 9
Potpis
u
liniji imas jednu zatvorenu zagradu vise nego sto imas otvorenih zagrada .. ili izbaci zatvorenu zagradu na kraju reda ili dodaj negde otvorenu
Code:
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='') AND (n.prezime LIKE '",pprezime,"%') OR pprezime IS NULL OR pprezime='')
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='') AND (n.prezime LIKE '",pprezime,"%') OR pprezime IS NULL OR pprezime='')
liniji imas jednu zatvorenu zagradu vise nego sto imas otvorenih zagrada .. ili izbaci zatvorenu zagradu na kraju reda ili dodaj negde otvorenu
Potpis
Code (sql):
-- --------------------------------------------------------------------------------
-- Routine DDL
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`pravni`@`localhost` PROCEDURE `SP_PRETRAZI_NASTAVNIKA2`(
IN pime VARCHAR(25), IN pprezime VARCHAR(35), IN pzvanje VARCHAR(25),
IN pkatedra VARCHAR(40), IN brojredova INT, IN poffset INT)
BEGIN
SET names utf8;
SET @q := CONCAT("
SELECT n.ime AS ime, n.prezime AS prezime, z.naziv AS zvanje, k.naziv AS katedra, f.naziv AS funkcija, ra.naziv AS radnoangazovanje
FROM ((((((((NASTAVNIK N LEFT JOIN NASTAVNIK_ZVANJE NZ ON N.NastavnikID=NZ.NastavnikID) LEFT JOIN
ZVANJE Z ON z.zvanjeId=nz.zvanjeid) LEFT JOIN
KATEDRA K ON K.Katedraid=N.KatedraID) LEFT JOIN
NASTAVNIK_RADNO_ANGAZOVANJE NRA ON NRA.NastavnikID=N.NastavnikID) LEFT JOIN
RADNO_ANGAZOVANJE RA ON RA.TipRadnogAngazovanjaID=NRA.TipRadnogAngazovanjaID) LEFT JOIN
NASTAVNIK_FUNKCIJA NF ON NF.NastavnikID=N.NastavnikID) LEFT JOIN
FUNKCIJA F ON F.FunkcijaID=NF.FunkcijaID))
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='') AND ((n.prezime LIKE '",pprezime,"%') OR pprezime IS NULL OR pprezime='')
AND ((z.naziv LIKE '",pzvanje,"%') OR pzvanje IS NULL OR pzvanje='') AND ((k.naziv LIKE '",pkatedra,"%') OR pkatedra IS NULL OR pkatedra='')");
PREPARE stmt FROM @q;
EXECUTE stmt;
END
-- --------------------------------------------------------------------------------
-- Routine DDL
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE DEFINER=`pravni`@`localhost` PROCEDURE `SP_PRETRAZI_NASTAVNIKA2`(
IN pime VARCHAR(25), IN pprezime VARCHAR(35), IN pzvanje VARCHAR(25),
IN pkatedra VARCHAR(40), IN brojredova INT, IN poffset INT)
BEGIN
SET names utf8;
SET @q := CONCAT("
SELECT n.ime AS ime, n.prezime AS prezime, z.naziv AS zvanje, k.naziv AS katedra, f.naziv AS funkcija, ra.naziv AS radnoangazovanje
FROM ((((((((NASTAVNIK N LEFT JOIN NASTAVNIK_ZVANJE NZ ON N.NastavnikID=NZ.NastavnikID) LEFT JOIN
ZVANJE Z ON z.zvanjeId=nz.zvanjeid) LEFT JOIN
KATEDRA K ON K.Katedraid=N.KatedraID) LEFT JOIN
NASTAVNIK_RADNO_ANGAZOVANJE NRA ON NRA.NastavnikID=N.NastavnikID) LEFT JOIN
RADNO_ANGAZOVANJE RA ON RA.TipRadnogAngazovanjaID=NRA.TipRadnogAngazovanjaID) LEFT JOIN
NASTAVNIK_FUNKCIJA NF ON NF.NastavnikID=N.NastavnikID) LEFT JOIN
FUNKCIJA F ON F.FunkcijaID=NF.FunkcijaID))
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='') AND ((n.prezime LIKE '",pprezime,"%') OR pprezime IS NULL OR pprezime='')
AND ((z.naziv LIKE '",pzvanje,"%') OR pzvanje IS NULL OR pzvanje='') AND ((k.naziv LIKE '",pkatedra,"%') OR pkatedra IS NULL OR pkatedra='')");
PREPARE stmt FROM @q;
EXECUTE stmt;
END
Izbacio sam nepotrebnu zagradu ali mi sad prijavljuje sledeću grešku:
Code:
Error Code: 1054
Unknown column 'pime' in 'where clause'
Error Code: 1054
Unknown column 'pime' in 'where clause'
Potpis
izmenjeno 2 puta, poslednji put djoka_l 16.07.2010. u 11:46
Izmene poruke
- djoka_l16.07.2010. u 11:46zapis iz teksta poruke
- djoka_l16.07.2010. u 11:45zapis iz teksta poruke
Ne možeš da korisitiš varijable unutar stringa dinamičke SQL naredbe. Sad, ja nisam stručnjak za MySQL, na Oracle bazi bi se na mestima gde treba da dođu varijable stavili pozicioni parametri :1, :2, ... pa bi se onda napravio bind sa pravim parametrima. Ne znam kako bi to išlo u MySQL-u.
Sada si stigao, otprilike, onde gde sam ti rekao da je pravi put pre ne znam koliko postova i koliko tema, a to je da za ovakav tip upita treba koristiti dinamički SQL.
Recimo konstrukcija:
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='')
može sada lepo da se zameni na ovaj način
pa onda izređaš if uslove za prezime zvanje katedru i šta već sve imaš... Uzgred, ovo parče koda koji sam napisao verovatno nije sintaksno ispravno na MySql, shvati to kao pseudokod...
Na ovaj način ćeš konstruisati SELECT naredbu samo sa onim uslovima koji nisu prazni te ćeš dobiti jednostavniji i, verovatno, brži upit.
Sada si stigao, otprilike, onde gde sam ti rekao da je pravi put pre ne znam koliko postova i koliko tema, a to je da za ovakav tip upita treba koristiti dinamički SQL.
Recimo konstrukcija:
WHERE ((n.ime LIKE '", pime,"%') OR pime IS NULL OR pime='')
može sada lepo da se zameni na ovaj način
Code:
q:= UPIT_DO_WHERE_KLAUZULE;
veznik := " WHERE ";
if pime is not null then -- možda u MySql treba pime <> ""
q := concat( q, veznik, "n.ime like '", pime, "%'");
veznik := " AND ";
end if;
...
q:= UPIT_DO_WHERE_KLAUZULE;
veznik := " WHERE ";
if pime is not null then -- možda u MySql treba pime <> ""
q := concat( q, veznik, "n.ime like '", pime, "%'");
veznik := " AND ";
end if;
...
pa onda izređaš if uslove za prezime zvanje katedru i šta već sve imaš... Uzgred, ovo parče koda koji sam napisao verovatno nije sintaksno ispravno na MySql, shvati to kao pseudokod...
Na ovaj način ćeš konstruisati SELECT naredbu samo sa onim uslovima koji nisu prazni te ćeš dobiti jednostavniji i, verovatno, brži upit.
biske, valjda si svatio kako se kreira sql upit ... tj kako napunis string varijablu sa concat() pa je onda prepare pa exec ..
greska ti kaze da ti ne valja upit (imas kolonu koja ne valja) .. greska ti je u delu
tu treba
mozes u proceduri umesto
da stavis
da ti vrati upit koji je generisao
greska ti kaze da ti ne valja upit (imas kolonu koja ne valja) .. greska ti je u delu
Code:
OR pime IS NULL OR pime=''
OR pime IS NULL OR pime=''
tu treba
Code:
OR n.ime IS NULL OR n.ime=''
OR n.ime IS NULL OR n.ime=''
mozes u proceduri umesto
Code:
execute stmt;
execute stmt;
da stavis
Code:
select @q;
select @q;
da ti vrati upit koji je generisao