检查 `RECORD` 变量是否已初始化
Check if a `RECORD` variable is initialized
我正在尝试声明一个数据类型为 record
的变量,但是当没有结果可以用来填充它时我遇到了麻烦。下面是函数的简化模型:
CREATE OR REPLACE FUNCTION do_something()
RETURNS TRIGGER AS $$
DECLARE
engagement record;
BEGIN
SELECT code
INTO engagement
FROM "mainEngagement" me
WHERE me.value = NEW.id;
IF TG_OP = 'INSERT'
THEN
INSERT INTO engagement_details (code)
values (
case
when engagement is not null
then exists(select code from engagement where "value" = 'expected')
else false
end
);
ELSE
UPDATE engagement_details
SET
code = case
when engagement is not null
then exists(select 1 from engagement where "value" = 'expected')
else false
end
WHERE engagement_details.assessment_id = NEW.id;
END IF;
RAISE NOTICE 'Updated engagement_details: [%]', NEW;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
当触发器运行且 "mainEngagement" 中没有数据时,我在 INSERT 中收到错误:
ERROR: relation "engagement" does not exist
我找不到测试参与度是否已填充的方法。我搜索了很多堆栈溢出问题,但大多数人只是建议做 engagement := row(null)
,但 when engagement is not null
仍然对我不起作用。
使用IF NOT FOUND
:
SELECT code
INTO engagement
FROM "mainEngagement" me
WHERE me.value = NEW.id;
IF NOT FOUND
THEN
RAISE WARNING '|W| do_something(): engagement undefined'; -- report warning
RETURN; -- exit early, function cannot proceed
END IF;
我在这里遇到的问题是 RECORD
条目只能有一行作为结果。我试图 return 一个包含多行的值,然后 运行 记录上的 CASE
语句,这永远行不通。而是执行以下操作:
CREATE OR REPLACE FUNCTION do_something()
RETURNS TRIGGER AS $$
DECLARE
engagement boolean;
BEGIN
SELECT EXISTS (
SELECT 1 FROM engagement WHERE "value" = 'expected'
) INTO engagement;
IF TG_OP = 'INSERT'
THEN
INSERT INTO engagement_details (code)
values (engagement);
ELSE
UPDATE engagement_details
SET
code = engagement
WHERE engagement_details.assessment_id = NEW.id;
END IF;
RAISE NOTICE 'Updated engagement_details: [%]', NEW;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
更简单、更清晰且有效。
我正在尝试声明一个数据类型为 record
的变量,但是当没有结果可以用来填充它时我遇到了麻烦。下面是函数的简化模型:
CREATE OR REPLACE FUNCTION do_something()
RETURNS TRIGGER AS $$
DECLARE
engagement record;
BEGIN
SELECT code
INTO engagement
FROM "mainEngagement" me
WHERE me.value = NEW.id;
IF TG_OP = 'INSERT'
THEN
INSERT INTO engagement_details (code)
values (
case
when engagement is not null
then exists(select code from engagement where "value" = 'expected')
else false
end
);
ELSE
UPDATE engagement_details
SET
code = case
when engagement is not null
then exists(select 1 from engagement where "value" = 'expected')
else false
end
WHERE engagement_details.assessment_id = NEW.id;
END IF;
RAISE NOTICE 'Updated engagement_details: [%]', NEW;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
当触发器运行且 "mainEngagement" 中没有数据时,我在 INSERT 中收到错误:
ERROR: relation "engagement" does not exist
我找不到测试参与度是否已填充的方法。我搜索了很多堆栈溢出问题,但大多数人只是建议做 engagement := row(null)
,但 when engagement is not null
仍然对我不起作用。
使用IF NOT FOUND
:
SELECT code
INTO engagement
FROM "mainEngagement" me
WHERE me.value = NEW.id;
IF NOT FOUND
THEN
RAISE WARNING '|W| do_something(): engagement undefined'; -- report warning
RETURN; -- exit early, function cannot proceed
END IF;
我在这里遇到的问题是 RECORD
条目只能有一行作为结果。我试图 return 一个包含多行的值,然后 运行 记录上的 CASE
语句,这永远行不通。而是执行以下操作:
CREATE OR REPLACE FUNCTION do_something()
RETURNS TRIGGER AS $$
DECLARE
engagement boolean;
BEGIN
SELECT EXISTS (
SELECT 1 FROM engagement WHERE "value" = 'expected'
) INTO engagement;
IF TG_OP = 'INSERT'
THEN
INSERT INTO engagement_details (code)
values (engagement);
ELSE
UPDATE engagement_details
SET
code = engagement
WHERE engagement_details.assessment_id = NEW.id;
END IF;
RAISE NOTICE 'Updated engagement_details: [%]', NEW;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
更简单、更清晰且有效。