为PostgreSQL表创建别名

时间:2014-04-25 18:02:16

标签: postgresql database-design view plpgsql

我有一张叫做赋值的表。我希望能够使用assignments.column或homework.column读取/写入此表中的所有列,我该怎么做?

我知道这不是你通常会做的事情。我需要能够在短时间内提供向后兼容性。

我们有一个iOS应用程序,目前直接对数据库进行postgresql查询。我们正在更新所有应用以使用API​​。在构建API的过程中,开发人员决定更改表的名称,因为我们(愚蠢地)认为我们不需要向后兼容。

现在,V1.0和API都需要能够写入此表,所以我以后不必做一些伏都教来稍后传输/合并数据... 我们正在使用Ruby on Rails获取API。

3 个答案:

答案 0 :(得分:13)

使用Postgres 9.3,以下内容应该足够了:

  

创建视图作业AS SELECT * FROM作业;

这很有效,因为简单的视图可以自动更新(see docs)。

答案 1 :(得分:1)

以您正在进行的工作为基础:

触发功能

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;

触发

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

注释

  • 动态SQL(在UPDATE部分中)并不是绝对必要的,只是为了自动覆盖对表格布局的未来更改。表格和pk的名称仍然是硬编码的。

  • plpgsql assignment operator is :=

  • 在没有sub-block的情况下更简单且可能更便宜(与您一样)。

  • 使用(SELECT ($1).*)代替较短的VALUES $1来保留列名。

  • 我的命名约定:我为触发器函数添加了trg_,后跟一个表示目标表的缩写,最后是一个或多个标记insupdel分别用于INSERTUPDATEDELETE。触发器的名称是功能名称的副本,剥离了前两个部分。这纯粹是一种惯例和品味的问题,但事实证明这对我来说很有用,因为名字说明了目的并且仍然足够短。

  • 在已经提到的相关答案中有更多解释:
    Update multiple columns in a trigger function in plpgsql

答案 2 :(得分:0)

到目前为止,这是我使用触发功能的地方,我们将非常感谢任何反馈。它是http://vibhorkumar.wordpress.com/2011/10/28/instead-of-trigger/Update multiple columns in a trigger function in plpgsql

的组合

表:iassignments_assignments

列:

published_assignment_id
name
filepath
filename
link
teacher
due date
description
published
classrooms

查看:assignments_published - SELECT * FROM iassignments_assignments

assignments_published的触发功能

CREATE OR REPLACE FUNCTION assignments_published_trigger_func()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $function$
   BEGIN
      IF TG_OP = 'INSERT' THEN
        EXECUTE format('INSERT INTO %s SELECT ($1).*', 'iassignments_assignments')
        USING NEW;
        RETURN NEW;
      ELSIF TG_OP = 'UPDATE' THEN
        DECLARE
          tbl = 'iassignments_assignments';
          cols text;
          vals text;
        BEGIN
          SELECT INTO cols, vals
           string_agg(quote_ident(attname), ', ')
           ,string_agg('x.' || quote_ident(attname), ', ')
          FROM   pg_attribute
          WHERE  attrelid = tbl
          AND    NOT attisdropped   -- no dropped (dead) columns
          AND    attnum > 0;        -- no system columns

          EXECUTE format('
          UPDATE %s t
          SET   (%s) = (%s)
          FROM  (SELECT ($1).*) x
          WHERE  t.published_assignment_id = ($2).published_assignment_id'
          , tbl, cols, vals)
          USING NEW, OLD;

          RETURN NEW;
        END
      ELSIF TG_OP = 'DELETE' THEN
       DELETE FROM iassignments_assignments WHERE published_assignment_id=OLD.published_assignment_id;
       RETURN NULL;
      END IF;
      RETURN NEW;
    END;
$function$;

<强>触发

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

表:iassignments_classes

列:

class_assignment_id
guid
assignment_published_id

查看:assignments_class - SELECT * FROM assignments_classes

assignments_class的触发器功能

**一旦我收到对方的反馈并知道它的创建,我就会创建这个功能,所以我(希望)需要对此功能进行很少的更改。

<强>触发

CREATE TRIGGER assignments_class_trigger
INSTEAD OF INSERT OR UPDATE OR DELETE ON
assignments_class FOR EACH ROW EXECUTE PROCEDURE assignments_class_trigger_func();