1

Temat: Podfunkcja

Witam
Chciałbym zapytać czy można w funkcji utworzyć podfunkcje tzn działanie (część wspólna kodu dla wielu warunków) powtarzalne dla części tej funkcji, ale żeby nie tworzyć do tego celu nowej funkcji, która nie była by nigdzie więcej wykorzystywana.

Taki prosty przykład

funkcja(a,b)
{
if a>b then 0
  else
       a*b+3-2;
end if; 
if 2+4 >b then 2
  else
       a*b+3-2 + 5;  -- to samo co wcześniej tylko +5
end if; 
}

To taki mały przykład, chodzi mi o to żeby nie powielać działania a*b+3-2 tyle razy ile go potrzebuje, dlatego że jeżeli umieszczę go raz i potem się do niego odnoszę to jeżeli zajdzie jakaś potrzeba zmiany w tym działaniu to robię ją raz, a nie w każdym działaniu osobno np a*b+3-2 na a*b+2-3
Takie proste działanie mogę podstawić jako zmienna zmienna:=a*b+3-2 i odwoływać się do zmiennej, ale co innego kiedy wykonuje np selecta
Select pole from tabela where pole = zmienna_zależna_od_warunku_w_którym_jestem

Nie wiem czy wyraziłem się jasno, ale może ktoś coś podpowie.

Z góry dzięki

2

Odp: Podfunkcja

Ostatnio edytowany przez c_michal (2013-09-25 22:27:36)

3

Odp: Podfunkcja

Stosuję Select into
Nie wiem czy wyraziłem się jasno, ale jeżeli np: mam poniższy kod który wykorzystuje 2 razy w jednej funkcji to jeżeli go zmienię w jednym miejscu muszę pamiętać aby zmienić również w drugim. Gdyby ten kod był osobna funkcją do której bym się odwoływał, to poprawka w tej funkcji załatwia wszystko. Ale nie chce tworzyć nowej funkcji (zaśmiecać bazy) która była by używana tylko w jednym miejscu i nigdzie więcej.

select dzien_wolny into zmw_dzien_wolny from widok_harmonogramy
where nr_dnia = extract(dow from zm_data_pomocnicza) and dzien_wolny = true and
nr_typu_harmonogramu in (select nr_typu_harmonogramu from tab_harmonogramy_pracownikow where nr_pracownika = zm_nr_pracownika  and zm_data_pomocnicza between wazne_od and wazne_do);

4

Odp: Podfunkcja

a może tak
na początku funkcji deklarujesz prepare

PREPARE p_user (varchar,date) AS
    SELECT * FROM pg_shadow where usename ilike '%'||$1||'%' and $2>=coalesce(valuntil,current_date::timestamp) ;

potem wielokrotnie i z różnymi parametrami wykonujesz je
EXECUTE p_user into zmienna using current_user, current_date;

a na końcu
DEALLOCATE p_user;

PS pisze z pamięci wiec sprawdź sobie w helpie

5

Odp: Podfunkcja

Witam
Nie mogę się z tym uporać, robię taka prosta funkcję

CREATE OR REPLACE FUNCTION podfunkcja_test1 (zmienna varchar)
RETURNS varchar AS
$body$
declare
  zzz VARCHAR;
begin
   PREPARE podfunkcja (varchar,date) AS select CURRENT_USER;
    EXECUTE podfunkcja into zzz using current_user, current_date;
     DEALLOCATE podfunkcja;
    return 'www';
end;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY DEFINER
COST 100;

Polecenie:
select * from podfunkcja_test1 ('ss');

Dostaje: ERROR:  column "podfunkcja" does not exist

Nie wiem jak to ugryźć, w sieci nic konkretnego nie znalazłem
Wg mnie powinno się wykonać Prepare, "zdezaktywowac" i zwrócić wynik www

6

Odp: Podfunkcja

Ciekawe dlaczego nie działa taka konstrukcja, ale zobacz poniższy przykład - to chyba załatwia Twój problem

CREATE OR REPLACE FUNCTION podfunkcja_test1 (zmienna varchar,dzien date)
RETURNS varchar AS
$body$
declare
  zzz VARCHAR;
  sql varchar = 'SELECT count(*) FROM pg_shadow where usename ilike ''%''||$1||''%'' and $2>=coalesce(valuntil,current_date::timestamp);';
begin
    EXECUTE sql into zzz using zmienna,dzien;
    return zzz;
end;
$body$
LANGUAGE 'plpgsql'
VOLATILE
CALLED ON NULL INPUT
SECURITY DEFINER
COST 100;


select * from podfunkcja_test1 (current_user::varchar,current_date);

7

Odp: Podfunkcja

Dzięki, ta funkcja działa