Eksekusi Formula//Rumus Dalam Bentuk String (Postgres)
Beberapa waktu yang lalu, aku mengerjakan sebuah system untuk perhitungan hasil produksi menggunakan php + extjs, dengan postgres sebagai databasenya. Ada banyak rumus/formula yang digunakan dalam sekali produksi, awalnya aku langsung menempatkan rumus-rumus itu dalam script karena aku berpikir formula tidak akan berubah. Pemikiranku itu ternyata salah, formula bisa berubah sewaktu-waktu, dan menempatkan formula pada script langsung dengan situasi seperti ini akan konyol, mengingat system akan di handover oleh user awam.
Sempat mendapak kendala bagaimana melakukan eksekusi rumus yang disimpan dalam format string dalam field tabel. Setelah mencoba berbagai cara dan juga search permasalahan serupa akhirnya masalah terpecahkan. Berikut ini adalah cara-cara yang aku gunakan.
1. Buat sebuah fungsi di postgres (a function handler):
perintahnya:
CREATE FUNCTION plpgsql_call_handler() RETURNS language_handler AS
'$libdir/plpgsql' LANGUAGE C;
kemungkina akan terjadi error jika postgres belum install language 'plpgsql'2.
2. Buat language 'plpgsql'
CREATE TRUSTED LANGUAGE plpgsql
HANDLER "plpgsql_call_handler";
3. Jika perlu jalankan perintah dibawah ini:
GRANT USAGE ON LANGUAGE plpgsql TO public;
Selanjutnya, memulai membuat fungsi yang menjalankan rumus/formula yang disimpan dalam string tersebut:
contoh:
1. untuk kembalian fungsi hanya 1 nilai (value) saja
-- DROP FUNCTION gaji(integer); CREATE OR REPLACE FUNCTION gaji(integer) RETURNS numeric AS $BODY$ declare g text; ret numeric(10,2); begin select into g rumus from view_karyawan where id=$1; execute 'select ' || g || ' from view_karyawan where id=' || $1 into ret; return ret; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE COST 100; ALTER FUNCTION gaji(integer) OWNER TO postgres; Setelah function dibuat, letakkan item-item nilai yang akan di kalkulasi beserta rumusnya sejajar dalam 1 baris/row, jika ada relasi dengan banyak tabel bisa disederhanakan menggunakan query view atau temporary table sehingga dapat menyatukan semua field yang dibutuhkan dalam 1 record data. Contoh: test=# select * from view_karyawan ; id | hari | pokok |uang_makan| bonus |tunjangan|rumus ----+-----+-------+----------+-------+---------+------------------------------------ 1 | 25 |750000 |5000 | 50000 | 0 |(hari*uang_makan)+pokok+bonus 2 | 25 |750000 |5000 | 50000 |50000 |(hari*uang_makan)+pokok+bonus+tunjangan (2 rows) ex.1=*# selec id, nama, (select * from gaji(1))::numeric(9,2) as gaji from karyawan where id=1; id| nama | gaji --+------+------------ 1| si X | 925000.00 (1 row) ex.2=*# selec id, nama, (select * from gaji(2))::numeric(9,2) as gaji from karyawan where id=1; id| nama | gaji --+------+------------ 2| si Y | 975000.00 (1 row)
2. Untuk kembalian fungsi lebih dari 1 (array)
CREATE OR REPLACE FUNCTION fo_saco_warp(IN x integer, OUT te_warp numeric, OUT yc_lbs numeric, OUT yc_bales numeric, OUT sizing numeric) RETURNS record AS $BODY$ declare -- Declare aliases for user input. e_id ALIAS FOR $1; -- Declare variables to hold the formula. fte_warp TEXT; fyc_lbs TEXT; fyc_bales TEXT; fsizing TEXT; begin select INTO fte_warp, fyc_lbs, fyc_bales, fsizing f_te_warp, f_yc_warp_lbs, f_yc_warp_bales, sizing_length from saco_formula_dynamic_warp where seq_yarn_id=e_id; execute 'select ' || fte_warp ||',' || fyc_lbs ||',' || fyc_bales ||',' || fsizing ||' from saco_formula_dynamic_warp where seq_yarn_id=' || e_id into te_warp,yc_lbs,yc_bales,sizing; end; $BODY$ LANGUAGE 'plpgsql' VOLATILE COST 100; ALTER FUNCTION fo_saco_warp(integer) OWNER TO postgres;
Contoh untuk hasil eksekusi dengan kembalian lebih dari 1:
![]() | ||||||||||||||||||||
execute "string" formula |
Dengan kombinasi function postgres dan interface sederhana (kalkulator aneh) bisa menyesesaikan masalah kecil dengan system yang kubuat.
Komentar
Posting Komentar