[ biske86 @ 09.07.2010. 23:40 ] @
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.
[ bogdan.kecman @ 10.07.2010. 07:07 ] @
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> 


[ biske86 @ 15.07.2010. 15:18 ] @
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.

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
 
[ bogdan.kecman @ 15.07.2010. 17:01 ] @
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 ;


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
[ biske86 @ 15.07.2010. 19:44 ] @
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
[ bogdan.kecman @ 15.07.2010. 22:40 ] @
u

Code:

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
[ biske86 @ 16.07.2010. 01:08 ] @
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
 


Izbacio sam nepotrebnu zagradu ali mi sad prijavljuje sledeću grešku:

Code:
Error Code: 1054
Unknown column 'pime' in 'where clause'
[ djoka_l @ 16.07.2010. 10:32 ] @
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
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;
...

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.


[Ovu poruku je menjao djoka_l dana 16.07.2010. u 11:45 GMT+1]

[Ovu poruku je menjao djoka_l dana 16.07.2010. u 11:46 GMT+1]
[ bogdan.kecman @ 16.07.2010. 10:53 ] @
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

Code:

OR pime IS NULL OR pime=''


tu treba

Code:

OR n.ime IS NULL OR n.ime=''


mozes u proceduri umesto

Code:

execute stmt;


da stavis

Code:

select @q;


da ti vrati upit koji je generisao