Hazırlamak
Formülleriniz şöyle görünür:
d*b+(l*4+r)+(i/d)+s
Ben $n
doğrudan plpgsql değerleri ile değiştirilebilir böylece gösterim ile değişkenleri yerine EXECUTE
(aşağıya bakınız):
$1*$5+($3*4+$2)+($6/$1)+$4
Orijinal formüllerinizi ek olarak (insan gözü için) saklayabilir veya bu formu aşağıdaki gibi bir ifadeyle dinamik olarak oluşturabilirsiniz:
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');
Sadece çevirinizin sağlam olduğundan emin olun. Normal ifade ifadeleri için bazı açıklamalar :
\ m .. sadece bir kelimenin başında
eşleşir \ M .. sadece bir kelimenin sonunda eşleşir
4. parametre 'g'
.. global olarak değiştir
Çekirdek işlevi
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;
Aramak:
SELECT f_calc(1, 2, 3, 4.1, 5.2, 6.3, '$1*$5+($3*4+$2)+($6/$1)+$4');
İadeler:
29.6000000000000000
Önemli noktalar
Fonksiyon 6 değer parametresi ve formula text
7. Formülü son koydum, $1 .. $6
bunun yerine kullanabiliriz $2 .. $7
. Sadece okunabilirlik uğruna.
Uygun gördüğüm gibi değerler için veri türleri belirledim. Uygun tipler atayın (temel sağlık kontrollerini uygulamak için) veya sadece hepsini yapın numeric
:
USING
Madde ile dinamik yürütme için değerleri iletin. Bu, ileri geri dökümü önler ve her şeyi daha basit, daha güvenli ve daha hızlı hale getirir.
Bir OUT
parametre kullanıyorum çünkü bu daha zarif ve daha kısa sözdizimi sağlıyor. Bir sonlandırmaya RETURN
gerek yoktur, OUT parametrelerinin değeri otomatik olarak döndürülür.
@Chris tarafından güvenlik konusundaki dersi ve kılavuzdaki "GÜVENLİK TANIMLAMA İşlevlerini Güvenle Yazma" bölümünü düşünün . Tasarımımda, tek enjeksiyon noktası formülün kendisidir.
Aramayı daha da basitleştirmek için bazı parametreler için varsayılanları kullanabilirsiniz .