PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

MASUKKAN bilangan real dalam kolom berdasarkan kolom lain MASUKKAN LAMA

Berdasarkan dua persyaratan pertama, tidak ada yang salah dengan pemicu Anda, tetapi Anda dapat sangat menyederhanakannya:

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;

Namun, ada cara yang jauh lebih mudah, dan itu juga akan mengakomodasi persyaratan ketiga tanpa masalah. Daripada melihat nilai "time_index", Anda harus melihat nilai "time", karena itulah yang menjadi dasar "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;

Ini mengimplementasikan logika Anda, tetapi perhatikan bahwa ada beberapa potensi jebakan:

  • Bagaimana jika Anda memasukkan 'Lap' atau 'Break' sebelum 'Start'?
  • Bagaimana jika Anda memiliki lebih dari 9 peristiwa "fn_name" setelah 'Mulai' (bagian pecahan "time_index" akan bergulir ke bilangan bulat berikutnya)?

Anda tentu saja dapat melupakan bidang "time_index" dan pemicu sekaligus dan membuatnya dengan cepat dalam tampilan, jika model data Anda mengizinkannya (sama dengan "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. Fungsi jendela SQL dengan klausa where?

  2. Python psql \menyalin CSV ke server jauh

  3. Heroku:mengimpor dari S3 gagal

  4. Penyatuan koneksi Postgresql di Erlang

  5. Menyimpan data.frame besar ke dalam PostgreSQL dengan R