笔者一开始在pgsql创建触发器生成递增序列号一文中,当我尝试制作触发器函数时,我不断收到错误消息:无限执行了插入操作,导致栈溢出,抛出异常信息:error:SQL 错误 [54001]: ERROR: stack depth limit exceeded Hint: Increase the configuration parameter “max_stack_depth” (currently 4096kB), after ensuring the platform’s stack depth limit is adequate.
当时抛出异常时候创建的触发器函数如下:
sql">-- 创建触发器函数
CREATE OR REPLACE FUNCTION insert_increment_value_if_not_exists()
RETURNS TRIGGER AS $$
BEGIN
-- 检查 user_sequences 表中是否存在对应的 user_name
IF NOT EXISTS (
SELECT 1 FROM user_sequences WHERE user_name = NEW.user_name
) THEN
-- 在 user_sequences 表中插入新的记录
INSERT INTO user_sequences (user_name, increment_value)
VALUES (NEW.user_name, 1)
RETURN NEW;
else
UPDATE user_sequences
SET increment_value = increment_value + 1
WHERE user_name = NEW.user_name
;
END IF;
RETURN null;
END;
$$ LANGUAGE plpgsql;
-- 创建触发器
CREATE TRIGGER insert_increment_value_trigger
BEFORE INSERT ON user_sequences
FOR EACH ROW
EXECUTE FUNCTION insert_increment_value_if_not_exists();
我的触发条件就是在执行 insert 语句之前执行触发器里面的方法,初次调用的时候会进入第一个 sql 语句中,然后执行执行器里面的 insert 语句,然后又会触发触发器生成条件,在 BEFORE INSERT 触发器中再次 INSERT,导致对该第二个 INSERT 再次触发该触发器,再次触发 INSERT 并重新触发该触发器,依此类推。在初始化调用的时候,会一直触发,所有的函数调用都会耗尽堆栈。
解决办法:从触发功能中 BEGIN 删除 INSERT,返回 new 将使原始的 INSERT 触发语句完成。 BEFORE INSERT 触发器的触发功能中无需手动 INSERT。
修改后如下:
sql">-- 创建触发器函数
CREATE OR REPLACE FUNCTION insert_increment_value_if_not_exists()
RETURNS TRIGGER AS $$
BEGIN
-- 检查 user_sequences 表中是否存在对应的 user_name
IF NOT EXISTS (
SELECT 1 FROM user_sequences WHERE user_name = NEW.user_name
) THEN
-- 在 user_sequences 表中插入新的记录
RETURN NEW;
else
UPDATE user_sequences
SET increment_value = increment_value + 1
WHERE user_name = NEW.user_name
;
END IF;
RETURN null;
END;
$$ LANGUAGE plpgsql;
问题得以解决!