PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

CHÈN một số thực trong một cột dựa trên các cột khác CHÈN CŨ

Dựa trên hai yêu cầu đầu tiên, không có gì sai với trình kích hoạt của bạn, nhưng bạn có thể đơn giản hóa nó rất nhiều:

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;

Tuy nhiên, có một cách dễ dàng hơn nhiều và điều đó cũng sẽ đáp ứng được yêu cầu thứ ba mà không có vấn đề gì. Thay vì xem xét các giá trị "time_index", bạn nên xem xét giá trị "time", vì đó là những gì "time_index" dựa trên:

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;

Điều này thực hiện logic của bạn nhưng lưu ý rằng có một số cạm bẫy tiềm ẩn:

  • Điều gì sẽ xảy ra nếu bạn chèn 'Vòng quay' hoặc 'Ngắt' trước 'Bắt ​​đầu'?
  • Điều gì sẽ xảy ra nếu bạn có hơn 9 sự kiện "fn_name" sau 'Start' (phần phân số "time_index" sẽ chuyển sang số nguyên tiếp theo)?

Tất nhiên, bạn có thể quên hoàn toàn trường "time_index" và trình kích hoạt và tạo nó ngay lập tức trong một chế độ xem, nếu mô hình dữ liệu của bạn cho phép nó (tương tự với "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 để tìm điểm giữa giữa hai dấu thời gian

  2. Chèn, trên bản cập nhật trùng lặp trong PostgreSQL?

  3. PostgreSQL:Bỏ Cơ sở dữ liệu nhưng DB vẫn ở đó

  4. Sắp xếp postgreSQL với dấu thời gian

  5. Postgres:tổng hợp cột thành mảng