在 SELECT 查询中使用 postgresql 触发器函数中的 TG_TABLE_NAME

问题描述 投票:0回答:1

我有这个plpgsql触发功能


DECLARE
    prev_record daily_data%ROWTYPE;
BEGIN
    SELECT * INTO prev_record
    FROM ONLY TG_TABLE_NAME
    WHERE base = NEW.quote AND quote = 'USDT'
    ORDER BY timestamp DESC
    LIMIT 1;
    
    IF EXISTS prev_record THEN
        NEW.volume_usd := NEW.volume * prev_record.close;
    END IF;
    
    RETURN NEW;
END;

此函数的主要动机是从表中获取最新值,并用它来更新插入的新值的volume_usd。

这个函数将在很多表中使用,因此我在 select 语句中使用了

TG_TABLE_NAME
,但它似乎会抛出错误。

ERROR:  relation "tg_table_name" does not exist at character 41
2024-06-06 16:32:57.222 UTC [3253] QUERY:  SELECT *                      FROM ONLY TG_TABLE_NAME
             WHERE base = NEW.quote AND quote = 'USDT'
             ORDER BY timestamp DESC
             LIMIT 1
CONTEXT:  PL/pgSQL function update_volume_usd() line 5 at SQL statement

我看过执行函数,但认为它在这里没有用,因为我需要存储它

postgresql function triggers plpgsql postgresql-16
1个回答
0
投票

一般来说,标识符(包括表名)不能在普通 SQL 中参数化。为此,您需要带有

EXECUTE
的动态 SQL。

此外,

IF EXISTS prev_record THEN
不是有效的语法。
IF FOUND ...
可以代替它。

但是这个触发器的逻辑在并发写入负载下崩溃了。由于可见性问题,多个并发事务将计算出不一致的值。要么使用隔离级别

SERIALIZABLE
,要么根本不尝试这个魔术,而是存储普通值并在查询/视图/物化视图中跨时间序列进行计算。

更多详细信息取决于缺失的信息...

© www.soinside.com 2019 - 2024. All rights reserved.