sql >> データベース >  >> RDS >> PostgreSQL

他の列に基づいて列に実数を挿入しますOLDINSERTS

    最初の2つの要件に基づくと、トリガー自体に問題はありませんが、大幅に簡略化できます。

    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;
    

    ただし、はるかに簡単な方法があり、それでも問題なく3番目の要件に対応できます。 「time_index」の値を確認するのではなく、「time」の値を確認する必要があります。これは、「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. C#を使用してローカルSQLServerデータベースに接続する

    2. Railsdatabase.ymlを管理する方法

    3. 役割を設定するときにSQLalchemyが変更をコミットしない

    4. mysqlストアドプロシージャは、標準のクエリより20倍遅い