पहली दो आवश्यकताओं के आधार पर, आपके ट्रिगर में कुछ भी गलत नहीं है, लेकिन आप इसे बहुत सरल बना सकते हैं:
CREATE OR REPLACE FUNCTION timelog() RETURNS trigger AS $BODY$
DECLARE
t_ix real;
BEGIN
-- First check if you need to change NEW at all
IF (NEW.time_type = 'Start') OR (NEW.time_type = 'Lap') THEN
-- Now perform the expensive lookup for either of 'Start' or 'Lap'
SELECT time_index INTO t_ix
FROM table_ebscb_spa_log04
WHERE fn_name = NEW.fn_name
AND (time_type = 'Start' OR time_type = 'Lap')
ORDER BY stmtserial DESC LIMIT 1;
IF NOT FOUND THEN
-- Nothing found, so NEW.time_index := 1
NEW.time_index := 1;
ELSIF NEW.time_type = 'Start' THEN
-- Start new index for fn_name, discard any fractional part, then increment
NEW.time_index := floor(t_ix) + 1;
ELSE
-- Continue the lap, increment NEW.time_index
NEW.time_index := t_ix + 0.1;
END IF;
END IF;
RETURN NEW;
END; $BODY$ LANGUAGE plpgsql;
हालाँकि, एक बहुत आसान तरीका है, और वह बिना किसी समस्या के तीसरी आवश्यकता को भी पूरा करेगा। "time_index" मानों को देखने के बजाय, आपको "समय" मान को देखना चाहिए, क्योंकि यही "time_index" पर आधारित है:
CREATE OR REPLACE FUNCTION timelog() RETURNS trigger AS $BODY$
DECLARE
t_ix real;
BEGIN
-- Find the most recent entry for the same "fn_name" as the new record
SELECT time_index INTO t_ix
FROM table_ebscb_spa_log04
WHERE fn_name = NEW.fn_name
ORDER BY time DESC LIMIT 1;
-- Nothing found, so NEW.time_index := 1
IF NOT FOUND THEN
NEW.time_index := 1;
RETURN NEW;
END IF;
-- Some record exists, so update "time_index" based on previous record
CASE NEW.time_type
WHEN 'Start' THEN
-- Start new index for fn_name, discard any fractional part, then increment
NEW.time_index := floor(t_ix) + 1;
WHEN 'Lap' THEN
-- Continue the lap, increment NEW.time_index
NEW.time_index := t_ix + 0.1;
ELSE
-- Break, find previous break or start, increment by 0.1
SELECT time_index + 0.1 INTO NEW.time_index
FROM table_ebscb_spa_log04
WHERE fn_name = NEW.fn_name
AND (time_type = 'Start' OR time_type = 'Break')
ORDER BY time DESC LIMIT 1;
END CASE;
RETURN NEW;
END; $BODY$ LANGUAGE plpgsql;
यह आपके तर्क को लागू करता है लेकिन ध्यान दें कि कुछ संभावित नुकसान हैं:
- यदि आप 'प्रारंभ' से पहले 'गोद' या 'ब्रेक' डालते हैं तो क्या होगा?
- क्या होगा यदि आपके पास 'प्रारंभ' के बाद 9 से अधिक "fn_name" ईवेंट हैं ("time_index" भिन्नात्मक भाग अगले पूर्णांक पर आ जाएगा)?
आप निश्चित रूप से "time_index" फ़ील्ड और ट्रिगर को पूरी तरह से भूल सकते हैं और इसे एक दृश्य में फ्लाई पर उत्पन्न कर सकते हैं, यदि आपका डेटा मॉडल इसकी अनुमति देता है ("time_elapse" के साथ भी)।