【问题标题】:Loop through all user tables and insert row in each遍历所有用户表并在每个表中插入行
【发布时间】:2015-10-29 19:27:40
【问题描述】:

出于某种原因,我无法弄清楚这一点。我在 PostgreSQL 中有一个单独的模式,用于连接到服务器的每个用户的通知相关表。我的计划是让每个用户创建一个 TEMP 表来接收额外的通知信息,因为 Xojo 不支持 PostgreSQL 有效负载。
我觉得我开始接近了,所以我将发布我的触发器函数中的代码。

    DECLARE
        my_table    RECORD;
    BEGIN       
        FOR my_table IN 
            SELECT table_name
            FROM   information_schema.tables
            WHERE  table_schema = 'information_schema'
        LOOP
            INSERT INTO my_table.table_name (effected_row_id)
                VALUES (NEW.effected_row_id);
        END LOOP;
    END;

如果我错了,请告诉我,但我认为我的主要问题是弄清楚如何在 INSERT 语句中使用从 SELECT 语句返回的表名。

编辑: 这是我当前的触发函数

-- Function: notification.my_insert_trigger_function()

-- DROP FUNCTION notification.my_insert_trigger_function();

CREATE OR REPLACE FUNCTION notification.my_insert_trigger_function()
  RETURNS trigger AS
$BODY$DECLARE
    my_table    RECORD;
BEGIN       
    FOR my_table IN 
        SELECT table_name
        FROM   information_schema.tables
        WHERE  table_schema = 'notification' AND table_name <> 'notification_global' AND table_name <> 'switcher'
    LOOP
        EXECUTE(FORMAT($f$
        INSERT INTO %s (effected_row_username)
            VALUES (%s);
        $f$, 'notification.' || my_table.table_name, NEW.effected_row_username));
    END LOOP;
RETURN new;
END;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION notification.my_insert_trigger_function()
  OWNER TO serveradmin;

【问题讨论】:

  • 你能显示这个表的 DDL 吗?
  • 我愿意。你能告诉我怎么做吗?
  • 没关系,我想出了如何获得 DDL。你要哪张桌子?将在触发器中使用此函数的表还是此函数将影响的表之一?我会将后者添加到我的原始帖子中
  • 不是答案,但是在数据库中重复这样的任何结构对我来说就像缺少规范化,我建议您重新考虑您的设计。

标签: postgresql plpgsql


【解决方案1】:

您需要在触发函数中使用dynamic commandsformat() 函数通常很有帮助。

DECLARE
    my_table    RECORD;
BEGIN       
    FOR my_table IN 
        SELECT table_name
        FROM   information_schema.tables
        WHERE  table_schema = 'information_schema'
    LOOP
        EXECUTE(FORMAT($f$
        INSERT INTO %s (effected_row_id)
            VALUES (%s);
        $f$, my_table.tablename, NEW.effected_row_id));
    END LOOP;
END;

【讨论】:

  • 谢谢你 klin 我已经很接近完成这项工作了,但我仍然有一个问题。我使用了您的触发功能并进行了一些更改以完全符合我的需要。我的问题是我不断收到错误消息,说“serveradmin”列不存在。它从变量“New.effected_row_username”中获取“serveradmin”。我想弄清楚的是将文本从 'New.effected_row_username 传递到 effected_row_username 字段。我将在我的原始帖子中发布我修改过的代码。
  • 现在函数尝试插入VALUES(serveradmin),但它应该插入VALUES('serveradmin')。所以你必须添加撇号:VALUES('%s').
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-03
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多