You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL查询中声明变量检查数组包含性时遇对象未找到问题求解

解决PostgreSQL中声明变量检查数组列存在性时的对象未找到错误

报错原因

报错The specified object could not be found是因为你在创建临时表时使用了ON COMMIT DROP选项,再加上DO语句会在独立事务中执行——当DO块执行完毕,事务自动提交,临时表会被立即销毁,后续的SELECT语句自然找不到这个表。

解决方案

这里提供几种可行的解决方式,你可以根据需求选择:

方案1:移除临时表的自动销毁选项

去掉ON COMMIT DROP,让临时表在当前会话结束前保持存在,这样后续查询就能正常访问:

DO $$
DECLARE 
    thetag1 text = 'tag1';
    thetag2 text = 'tag2';
BEGIN 
    CREATE TEMP TABLE tmp_table AS
    SELECT DISTINCT 
        p.id
    FROM table_1 p
    WHERE thetag1 = ANY (p.tags)
      AND thetag2 = ANY (p.tags);
END $$;
SELECT * FROM tmp_table;

注:原代码中p.tags::text[]是多余的,p.tags本身就是character varying[]类型,PostgreSQL会自动处理与text变量的匹配,无需额外转换。

方案2:不用DO块,直接用CTE定义变量

这种方式更简洁,不需要创建临时表,直接返回查询结果:

WITH vars AS (
    SELECT 'tag1'::text AS thetag1, 'tag2'::text AS thetag2
)
SELECT DISTINCT p.id
FROM table_1 p, vars v
WHERE v.thetag1 = ANY (p.tags)
  AND v.thetag2 = ANY (p.tags);

方案3:在同一事务中执行DO块与查询

如果需要临时表自动销毁,可将DO块和查询放在同一个事务中,确保查询执行时临时表还存在,事务提交后自动删除:

BEGIN;
DO $$
DECLARE 
    thetag1 text = 'tag1';
    thetag2 text = 'tag2';
BEGIN 
    CREATE TEMP TABLE tmp_table ON COMMIT DROP AS
    SELECT DISTINCT 
        p.id
    FROM table_1 p
    WHERE thetag1 = ANY (p.tags)
      AND thetag2 = ANY (p.tags);
END $$;
SELECT * FROM tmp_table;
COMMIT;

内容的提问来源于stack exchange,提问作者gilda753

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:32:23