Przygotować
Twoje formuły wyglądają tak:
d*b+(l*4+r)+(i/d)+s
$n
Zastąpiłbym zmienne notacją, aby można je było zastąpić wartościami bezpośrednio w plpgsql EXECUTE
(patrz poniżej):
$1*$5+($3*4+$2)+($6/$1)+$4
Możesz dodatkowo przechowywać oryginalne formuły (dla ludzkiego oka) lub dynamicznie generować ten formularz z wyrażeniem:
SELECT regexp_replace(regexp_replace(regexp_replace(
regexp_replace(regexp_replace(regexp_replace(
'd*b+(l*4+r)+(i/d)+s'
, '\md\M', '$1', 'g')
, '\mr\M', '$2', 'g')
, '\ml\M', '$3', 'g')
, '\ms\M', '$4', 'g')
, '\mb\M', '$5', 'g')
, '\mi\M', '$6', 'g');
Tylko upewnij się, że tłumaczenie jest prawidłowe. Kilka wyjaśnień wyrażeń regularnych :
\ m .. dopasowuje tylko na początku słowa
\ M .. dopasowuje tylko na końcu słowa
Czwarty parametr 'g'
... wymienić globalnie
Funkcja podstawowa
CREATE OR REPLACE FUNCTION f_calc(
d int -- days worked that month
,r int -- new nodes accuired
,l int -- loyalty score
,s numeric -- subagent commission
,b numeric -- base rate
,i numeric -- revenue gained
,formula text
,OUT result numeric
) RETURNS numeric AS
$func$
BEGIN
EXECUTE 'SELECT '|| formula
INTO result
USING $1, $2, $3, $4, $5, $6;
END
$func$ LANGUAGE plpgsql SECURITY DEFINER IMMUTABLE;
Połączenie:
SELECT f_calc(1, 2, 3, 4.1, 5.2, 6.3, '$1*$5+($3*4+$2)+($6/$1)+$4');
Zwroty:
29.6000000000000000
Najważniejsze punkty
Funkcja przyjmuje parametr 6 wartości i zajmuje 7 formula text
miejsce. Stawiam formułę na końcu, abyśmy mogli użyć $1 .. $6
zamiast $2 .. $7
. Tylko ze względu na czytelność.
Przypisałem typy danych do wartości, które uznałem za stosowne. Przypisz odpowiednie typy (w celu wprowadzenia podstawowych kontroli poczytalności) lub po prostu wykonaj je wszystkie numeric
:
Przekaż wartości do dynamicznego wykonania z USING
klauzulą. Pozwala to uniknąć rzucania w tę iz powrotem, a wszystko jest prostsze, bezpieczniejsze i szybsze.
Używam OUT
parametru, ponieważ jest on bardziej elegancki i zapewnia krótszą, bardziej przejrzystą składnię. Ostateczny RETURN
nie jest potrzebny, wartości parametrów OUT są zwracane automatycznie.
Rozważ wykład @Chris na temat bezpieczeństwa i rozdział „Pisanie DEFINICERA BEZPIECZEŃSTWA w bezpieczny sposób” w podręczniku. W moim projekcie pojedynczym punktem wstrzyknięcia jest sama formuła.
Możesz użyć wartości domyślnych dla niektórych parametrów w celu dalszego uproszczenia połączenia.