CASE 在检查表达式之前尝试计算子表达式

问题描述 投票:0回答:1

PostgreSQL 版本:15

我有带有动态列的动态表,我需要计算一些抽象属性

length
。如果列是数组那么我需要使用
array_length
函数,如果列是字符串那么
length

我尝试使用

CASE WHEN THEN

SELECT system_id
FROM models."model_e8467f0e-780d-45d0-b665-290452d0eae1"
WHERE (
    (
        SELECT CASE (SELECT element_type FROM elements WHERE id = '80bbc0ee-9f0b-4b16-9188-7d0b63c7c45d'::UUID)
            WHEN 4 THEN length("element_80bbc0ee-9f0b-4b16-9188-7d0b63c7c45d")
            WHEN 5 THEN array_length("element_80bbc0ee-9f0b-4b16-9188-7d0b63c7c45d", 1)
            WHEN 6 THEN (
                SELECT COUNT(child_id)
                FROM m2m_entry_n_entry_element_values
                WHERE parent_id = system_id
            )
        END
    ) >= 1
) 

在此示例中,

elements
表中的列具有
element_type = 6
,因此应触发最后一个分支。但是引发了
function length(uuid[]) does not exist
错误,这意味着 postgres 尝试计算第一个子表达式,尽管文档说明如下:

CASE 表达式不会计算任何不需要确定结果的子表达式。

postgresql case
1个回答
0
投票

Postgres 在运行查询之前会经历一个多阶段过程。即使它不调用相关函数,它也可以确定每个子表达式是什么。 Postgres 必须计划如何执行查询以及可以应用哪些优化。

提前通知您可能是一个更好的策略,而不是强迫您在失败之前等待长时间运行的查询。

有关 Postgres 正在做什么的详细信息,请参阅此处的文档:https://www.postgresql.org/docs/current/overview.html

© www.soinside.com 2019 - 2024. All rights reserved.