PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

अन्य कॉलम के आधार पर एक कॉलम में एक वास्तविक संख्या डालें पुराने INSERTs

पहली दो आवश्यकताओं के आधार पर, आपके ट्रिगर में कुछ भी गलत नहीं है, लेकिन आप इसे बहुत सरल बना सकते हैं:

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" के साथ भी)।




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. क्या PostgreSQL में एक चर नाम के साथ एक तालिका बनाना संभव है?

  2. पोस्टग्रेज में डुप्लिकेट हटाएं

  3. पैरामीटर NULL होने पर WHERE क्लॉज से शर्तों को कैसे हटाएं

  4. पोस्टग्रेज़ सेलेक्ट स्टेटमेंट में किसी अन्य तालिका में पंक्तियों की संख्या का चयन करें

  5. PostgreSQL Upsert WHERE क्लॉज के साथ