Create Alias for PostgreSQL Table

前端 未结 3 2304
被撕碎了的回忆
被撕碎了的回忆 2021-02-19 19:57

I have a table called assignments. I would like to be able to read/write to all the columns in this table using either assignments.column or homework.column, how can I do this?<

3条回答
  •  迷失自我
    2021-02-19 20:41

    Building on your work in progress:

    Trigger function

    CREATE OR REPLACE FUNCTION trg_ia_insupdel()
      RETURNS TRIGGER AS
    $func$
    DECLARE
       _tbl  CONSTANT regclass := 'iassignments_assignments';
       _cols text;
       _vals text;
    BEGIN
    
    CASE TG_OP
    WHEN 'INSERT' THEN
    
       INSERT INTO iassignments_assignments
       VALUES NEW;
    
       RETURN NEW;
    
    WHEN 'UPDATE' THEN
       SELECT INTO _cols, _vals
              string_agg(quote_ident(attname), ', ')   -- incl. pk col!
             ,string_agg('n.' || quote_ident(attname), ', ')
       FROM   pg_attribute
       WHERE  attrelid = _tbl        -- _tbl converted to oid automatically
       AND    attnum > 0             -- no system columns
       AND    NOT attisdropped;      -- no dropped (dead) columns
    
       EXECUTE format('
          UPDATE %s t
          SET   (%s) = (%s)
          FROM  (SELECT ($1).*) n
          WHERE    t.published_assignment_id
              = ($2).published_assignment_id' -- match to OLD value of pk
        , _tbl, _cols, _vals)        -- _tbl converted to text automatically
       USING NEW, OLD;
    
       RETURN NEW;
    
    WHEN 'DELETE' THEN
       DELETE FROM iassignments_assignments
       WHERE  published_assignment_id = OLD.published_assignment_id;
    
       RETURN OLD;
    END CASE;
    
    RETURN NULL;  -- control should never reach this
    
    END
    $func$ LANGUAGE plpgsql;
    

    Trigger

    CREATE TRIGGER insupbef
    INSTEAD OF INSERT OR UPDATE OR DELETE ON assignments_published
    FOR EACH ROW EXECUTE PROCEDURE trg_ia_insupdel();
    

    Notes

    • Dynamic SQL (in the UPDATE section) is not strictly necessary, only to cover future changes to the table layout automatically. The names of the table and the pk are still hard coded.

    • plpgsql assignment operator is :=

    • Simpler and probably cheaper without sub-block (like you had).

    • Using (SELECT ($1).*) instead of the shorter VALUES $1 to preserve column names.

    • My naming convention: I prepend trg_ for trigger functions, followed by an abbreviation indicating the target table and finally one or more of the the tokens ins, up and del for INSERT, UPDATE and DELETE respectively. The name of the trigger is a copy of the function name, stripped of the first two parts. This is purely a matter of convention and taste but has proven useful for me since the names tell the purpose and are still short enough.

    • More explanation in the related answer that has already been mentioned:
      Update multiple columns in a trigger function in plpgsql

提交回复
热议问题