我正在创建一个触发器,该触发器在表上执行INSERT时触发,并且我希望记录插入的表的结构,因此我编写了以下函数
CREATE OR REPLACE FUNCTION update_table_log_received()
RETURNS TRIGGER AS $$
DECLARE
added_column TEXT;
target_table_name TEXT;
old_column text;
BEGIN
-- Check if a new column has been added
IF (TG_OP = 'INSERT') THEN
added_column := NEW."COLUMN_NAME";
target_table_name := NEW."TABLE_NAME";
END IF;
SELECT column_name into old_column
FROM information_schema."columns"
WHERE table_schema = 'items'
and table_name = LOWER(NEW."TABLE_NAME")
and column_name = LOWER(NEW."COLUMN_NAME");
if (coalesce(old_column,'')='' or old_column='' or old_column = added_column) THEN
-- If a new column has been added
IF (Lower(added_column) != 'sync') then
-- Add the new column to the target table
EXECUTE 'ALTER TABLE items.' || LOWER(target_table_name)|| ' ADD COLUMN ' || LOWER(added_column) || ' VARCHAR(50)';
END IF;
end if;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
由该触发器执行:
CREATE TRIGGER update_table_log_received_trigger
AFTER INSERT
ON items."TABLE_LOG_RECEIVED"
FOR EACH ROW
EXECUTE FUNCTION update_table_log_received();
返回的异常如下:
!错误:关系y的列x已存在其中:指令SQL修改表项。添加列x变量字符(50)
我现在的问题是,它不应该通过If检查(我粘贴的代码后,许多修改,我有两个if条件,做同样的事情,只是因为),我调试和记录的语句,注意到我的函数内的选择查询返回空显然。我也试图使用“USING NEW”,但我不是Maven,所以我不能使它工作
是声明的变量没有从“NEW”记录填充的问题,还是我执行了错误的选择语句?
EDIT:tl;dr对于我的问题,我希望每当Database 2中的同一个表(具有相同的结构)从Database 1中更改时,无论是添加列还是更改列,我都要更新该表,此时我停留在添加列的第一个问题上。
我将表的结构作为字符串记录到一个新表中,并将其与Database 2同步,然后让触发器从Database 1中更改相同的已更改表,希望现在这样做更有意义。
记录所有表结构的Database 1 log_table:x1c 0d1x db2 log_table_received,其是每当插入新值时执行触发器的log_table的副本;
2条答案
按热度按时间14ifxucb1#
请尝试以下语法:
我试过我的DB这是工程。你可以改变一些细节自己。
mcvgt66p2#
已修复;问题应为:
参考文件:How to add column if not exists on PostgreSQL?
如何检查给定模式中是否存在表
How to get a list column names and datatypes of a table in PostgreSQL?
基本上,information_schema只能由所有者访问,即用户或(i)查询时看到结果,但在脚本内部执行时返回FALSE更多详细信息,请单击此处:https://stackoverflow.com/a/24089729/15170264
为安全起见,在使用CTE修复后完全触发以查询pg_catalog,还在我的执行查询中添加了
ADD COLUMN IF NOT EXISTS
变量old_column存储else条件消息,但不返回它,如果它是一个简单的函数,则会返回它。