我有这个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
我看过执行函数,但认为它在这里没有用,因为我需要存储它
一般来说,标识符(包括表名)不能在普通 SQL 中参数化。为此,您需要带有
EXECUTE
的动态 SQL。
此外,
IF EXISTS prev_record THEN
不是有效的语法。 IF FOUND ...
可以代替它。
但是这个触发器的逻辑在并发写入负载下崩溃了。由于可见性问题,多个并发事务将计算出不一致的值。要么使用隔离级别
SERIALIZABLE
,要么根本不尝试这个魔术,而是存储普通值并在查询/视图/物化视图中跨时间序列进行计算。
更多详细信息取决于缺失的信息...