header image

Prenos Accessovih “domain” funkcij na MySQL

Objavil: P.J. | 2.11.2010 | Brez komentarjev |

Človek se kmalu navadi nekega orodja in ena od stvari v MS Accessu, ki so zelo priročne, so t.i. “domain functions”, torej funkcije, ki omogočajo neposredno poizvedovanje po praviloma nepovezanih tabelah. Predvsem sem notri spadajo DLookUp, DMax in DMin, sem ter tja morda še DCount. Pa sem pomislil, ali bi bilo mogoče kaj takega narediti še na MySQL strežniku.

Ker sem pristaš reka, da se da vse -je pa odvisno od volje, časa in denarja, sem se kar lotil zadeve. In prišel do ugodnih rezultatov, čeprav ne čisto takšnih, kot bi si želel. Pa si poglejmo, kako zadeva zgleda v praksi. Kaj sploh želim storiti? V MS Accessu klic funkcijezgleda tako:

DMax("ime_polja" , "ime_tabele" , "pogoj = vrednost")

Ni težko uganiti, kaj takšna funkcija v resnici naredi. Iz vhodnih parametrov sestavi poizvedbo v obliki:

SELECT MAX(ime_polja) FROM me_tabele WHERE pogoj = vrednost

in vrne njen rezultat. Naša naloga je torej spisati funkcijo na MySQL strežniku, ki bo iz vhodnih parametrov sestavila takšen niz in izvedla poizvedbo za nas. Zadeva torej po pričakovanjih zgleda nekako tako:

CREATE PROCEDURE `DMAX`(fld VARCHAR(25), tbl VARCHAR(25), flt VARCHAR(250))
BEGIN

  SET @sql_txt :=
    CONCAT(
      'SELECT MAX(', fld, ') INTO @rc FROM ', tbl,
      CASE WHEN flt IS NOT NULL
      THEN CONCAT(' WHERE ', flt)
      ELSE ''
      END
  );

 ...

END

Verjetno je večina opazila, da sem uporabil oznako PROCEDURE in ne FUNCTION. Zakaj? Enostavno za to, ker MySQL ne dovoljuje uporabe dinamičnih SQL stavkov v funkcijah. Kako pa sedaj izvedemo poizvedbo, katere besedilo smo oblikovali zgoraj. V ta namen je na MySQL strežniku na voljo ukaz PREPARE. V našem primeru torej

...
PREPARE stmt FROM @sql_txt;
...

Sedaj je besedilo, ki smo ga sestavili v SQL poizvedbo pripravljeno za izvedbo. Kadarkoli bi želeli, bi ga lahko poklicali po njegovem imenu – v našem primeru stmt. To storimo z ukazom EXECUTE.

...
EXECUTE stmt;
...

Če se sedaj ozremo zgoraj v samo besedilo SQL poizvedbe, lahko vidimo, da smo rezultat shranili v spremenljivko @rc. Ta je določena na ravni seje (kakor vse spremenljivke predznačene z @). Torej jo lahko kadarkoli znotraj seje tudi preberemo z ukazom SELECT ali tako, da jo priredimo kaki drugi spremenljivki.

Na koncu celotna skripta, ki definira našo proceduro zgleda nekako tako, kot je vidno v primeru spodaj:

CREATE PROCEDURE `DMAX`(fld VARCHAR(25), tbl VARCHAR(25), flt VARCHAR(250))
BEGIN

  SET @sql_txt :=
    CONCAT(
      'SELECT MAX(', fld, ') INTO @rc FROM ', tbl,
      CASE WHEN flt IS NOT NULL
      THEN CONCAT(' WHERE ', flt)
      ELSE ''
      END,
      ' LIMIT 1' 
    );

 PREPARE stmt FROM @sql_txt;
 EXECUTE stmt;

 SELECT @rc;

  DEALLOCATE PREPARE stmt;

END $$

DELIMITER ;

Našo proceduro lahko sedaj kadarkoli pokličemo z ukazom CALL. Pri klicu iz VBA-ja, PHP-ja, itd. postopamo enako, kakor z drugimi tekstovnimi poizvedbami. Pošljemo torej vhodno besedilo v obliki klica “CALL DMAX(…)”, za rezultat pa bomo dobili sicer eno samo vrstico in eno samo polje, a sicer nič drugače, kakor ga dobimo ponavadi.

  • Share/Bookmark
Zapisano pod: Programiranje, Zbirke podatkov
Tags: , , , , ,

Pustite komentar

Tvoj odziv :

Komentiranje iz tujine je omogočeno zgolj prijavljenim uporabnikom !

Kategorije