发布
社区首页 >问答首页 >从%current%表中选择的PostgreSQL触发器函数

从%current%表中选择的PostgreSQL触发器函数
EN

Database Administration用户
提问于 2015-08-26 00:47:35
回答 3查看 7.6K关注 0票数 7

我有多个具有相同列名的表,它们仅在列值上有所不同,例如:

代码语言:javascript
代码运行次数:0
复制
tbl_log_a
tbl_log_b
tbl_log_c
...

从a到z的26个表。每个表都有一个触发器,该触发器调用一个触发器函数,该函数执行完全相同的操作:

代码语言:javascript
代码运行次数:0
复制
SELECT columnname FROM tbl_log_a

除此之外,我所有的触发函数都做同样的事情。它们的不同之处在于:

代码语言:javascript
代码运行次数:0
复制
select columnname FROM tbl_log_a
select columnname FROM tbl_log_b
select columnname FROM tbl_log_c
...

因此,我必须创建26个触发器函数,每个tbl_log_%letter%一个。是否有一种方法可以告诉触发器函数:

代码语言:javascript
代码运行次数:0
复制
SELECT columnname FROM %currenttable%

%currenttable%是指放置触发器的表。或者:

代码语言:javascript
代码运行次数:0
复制
SELECT columnname FROM tbl_log_%letter%

在Postgres 9.1中有可能吗?我正在阅读关于动态确定的表。有线索吗?我希望将表名本身存储在一个变量中,而不是存储在该表中的列中,因为触发器函数在该表中的多个列上工作。

代码语言:javascript
代码运行次数:0
复制
TG_TABLE_NAME
TG_TABLE_SCHEMA
EN

回答 3

Database Administration用户

回答已采纳

发布于 2015-08-26 01:50:42

我建议您使用触发器参数,但实际上没有必要。您可以使用自动变量 TG_TABLE_SCHEMATG_TABLE_NAME,也可以使用TG_RELID。这些与动态SQL的EXECUTE一起,允许您做您想做的事情:

代码语言:javascript
代码运行次数:0
复制
BEGIN
    EXECUTE format('SELECT colname FROM %I', TG_RELID)
END;

代码语言:javascript
代码运行次数:0
复制
BEGIN
    EXECUTE format('SELECT colname FROM %I.%I', TG_TABLE_SCHEMA, TG_TABLE_NAME)
END;

(当然,由于SELECT没有数据的目的地,这些数据将无法正常工作。您必须使用EXECUTE format(..) INTO ...将结果存储到DECLAREd变量中)。

代码语言:javascript
代码运行次数:0
复制
DECLARE
    _colvar integer;
BEGIN
    EXECUTE format('SELECT colname FROM %I.%I', TG_TABLE_SCHEMA, TG_TABLE_NAME) INTO _colvar;
    RAISE NOTICE 'colname value was %',_colvar;
END;
票数 10
EN

Database Administration用户

发布于 2015-08-26 14:56:00

在plpgsql中,与虚SELECT columnname FROM %currenttable%对应的实际语法是:

代码语言:javascript
代码运行次数:0
复制
execute format('SELECT columnname FROM %I.%I',
                TG_TABLE_SCHEMA, TG_TABLE_NAME);

TG_*内置变量记录在触发程序中,executeformat plpgsql构造在基本陈述中。

上面的查询本身是荒谬的(它选择不去任何地方的结果);目的只是显示可以构建实际查询的基本语法。

票数 3
EN

Database Administration用户

发布于 2015-08-26 15:20:48

或者您可以使用TG_RELID,但是由于它的数据类型是普通的oid,而不是regclass,所以必须显式地将其转换为regclass,以获得对模式限定的自动转换(仅在当前search_path需要的情况下),并明确转义表名。文件:

TG_RELID数据类型oid;引发触发器调用的表的对象ID。

大胆强调我的。我不知道为什么他们不让它regclass开始.

代码语言:javascript
代码运行次数:0
复制
EXECUTE format('SELECT columnname FROM %s', TG_RELID::regclass);

现在还不清楚你对结果做了什么。通常,您可以在INSERT / UPDATE / DELETE语句或将结果写入变量中使用它:

代码语言:javascript
代码运行次数:0
复制
EXECUTE format('SELECT columnname FROM %s', TG_RELID::regclass)
INTO my_variable;

只分配第一个值。如果SELECT找到更多行,则其余行将被丢弃。您可能需要添加ORDER BY ... LIMIT 1

相关信息:

票数 3
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/112184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档