เตรียมการ
สูตรของคุณมีลักษณะดังนี้:
d*b+(l*4+r)+(i/d)+s
ฉันจะแทนที่ตัวแปรด้วย$n
สัญกรณ์เพื่อให้พวกเขาสามารถแทนที่ด้วยค่าโดยตรงใน plpgsql EXECUTE
(ดูด้านล่าง):
$1*$5+($3*4+$2)+($6/$1)+$4
คุณสามารถจัดเก็บสูตรดั้งเดิมของคุณเพิ่มเติม (สำหรับสายตามนุษย์) หรือสร้างแบบฟอร์มนี้แบบไดนามิกด้วยนิพจน์เช่น:
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');
ตรวจสอบให้แน่ใจว่าคุณแปลเสียง คำอธิบายบางอย่างสำหรับการแสดงออก regexp :
\ m .. จับคู่เฉพาะตอนต้นของคำ
\ M .. จับคู่เฉพาะตอนท้ายของคำ
พารามิเตอร์ที่ 4 'g'
.. แทนที่ทั้งหมด
ฟังก์ชั่นหลัก
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;
โทร:
SELECT f_calc(1, 2, 3, 4.1, 5.2, 6.3, '$1*$5+($3*4+$2)+($6/$1)+$4');
ผลตอบแทน:
29.6000000000000000
ประเด็นสำคัญ
ฟังก์ชั่นใช้พารามิเตอร์ค่า 6 และformula text
เป็น 7 ฉันใส่สูตรที่ผ่านมาดังนั้นเราสามารถใช้แทน$1 .. $6
$2 .. $7
เพียงเพื่อประโยชน์ในการอ่าน
ฉันกำหนดประเภทข้อมูลสำหรับค่าตามที่เห็นเหมาะสม กำหนดประเภทที่เหมาะสม (เพื่อใช้การตรวจสุขภาพพื้นฐาน) หรือทำให้ทั้งหมดnumeric
:
ส่งผ่านค่าสำหรับการดำเนินการแบบไดนามิกด้วยส่วนUSING
คำสั่ง สิ่งนี้หลีกเลี่ยงการร่ายไปมาและทำให้ทุกอย่างง่ายขึ้นปลอดภัยขึ้นและเร็วขึ้น
ฉันใช้OUT
พารามิเตอร์เพราะมันดูดีกว่าและใช้ไวยากรณ์ที่สั้นกว่า สุดท้ายRETURN
ไม่จำเป็นต้องค่าของพารามิเตอร์ OUT (s) จะถูกส่งกลับโดยอัตโนมัติ
พิจารณาการบรรยายเรื่องความปลอดภัยโดย @Chrisและบท"การเขียนฟังก์ชั่นความปลอดภัยอย่างปลอดภัย"ในคู่มือ ในการออกแบบของฉันจุดเดียวของการฉีดคือสูตรเอง
คุณสามารถใช้ค่าเริ่มต้นสำหรับพารามิเตอร์บางอย่างเพื่อให้การโทรง่ายขึ้น