为啥在我的 Postgres 函数中使用 IF 语句时出现语法错误?

Posted

技术标签:

【中文标题】为啥在我的 Postgres 函数中使用 IF 语句时出现语法错误?【英文标题】:Why am I getting a syntax error when using an IF statement in my Postgres function?为什么在我的 Postgres 函数中使用 IF 语句时出现语法错误? 【发布时间】:2022-01-20 01:08:43 【问题描述】:

我正在创建一个函数,允许我有条件地更新表中的特定列。但是,当我尝试运行以下代码时,我收到一条错误消息,表明“IF”处或附近存在语法错误。我对 Postgres 有点陌生,所以很有可能。我无法理解 Postgres 中的一些概念/语法。有人可以通过指出我必须犯的错误来帮助我吗?

CREATE OR REPLACE FUNCTION profiles.do_something(
        p_id UUID,
        p_condition1 BOOLEAN,
        p_condition2 BOOLEAN,
        p_condition3 BOOLEAN
    ) 
RETURNS void AS $$
BEGIN

    IF p_condition1 IS TRUE THEN
        UPDATE tablename SET column1 = null WHERE member_id = p_id;
    END IF;

    IF p_condition2 IS TRUE THEN
        UPDATE tablename SET column2 = null WHERE member_id = p_id;
    END IF;

    IF p_condition3 IS TRUE THEN
        UPDATE tablename SET column3 = null WHERE member_id = p_id;
    END IF;

END;
$$ LANGUAGE 'sql';

【问题讨论】:

【参考方案1】:

tl;dr $$ LANGUAGE 'plpgsql'

$$ LANGUAGE 'sql';
            ^^^^^

你被告知将函数体解析为sql。在 SQL 中,begin 是一个启动事务的语句。

create or replace function test1()
returns void
language sql
as $$
-- In SQL, begin starts a transaction.
-- note the ; to end the statement.
begin;
    -- Do some valid SQL.
    select 1;
-- In SQL, end ends the transaction.
end;
$$;

在 SQL 中你写了 begin if ... 这是一个语法错误。

您使用的语言是plpgsql。在 plpgsql 中,begin 是一个开始一个块的关键字。

create or replace function test1()
returns void
language plpgsql
as $$
-- In PL/pgSQL, begin starts a block
-- note the lack of ;
begin
    -- Do some valid SQL.
    select 1;
-- In PL/pgSQL, end ends the block
end;
$$;

【讨论】:

谢谢。虽然现在我想知道这应该如何写成一个有效的 SQL 函数而不是 plpgsql。我对 SQL 的搜索最终与 MS-SQL 相关,我认为这与 postgres 中的“sql”不同? @Michael MS-SQL 喜欢将自己称为“SQL Server”。不,“SQL”指的是他们理论上遵循的SQL Standard。 SQL 不是过程语言,因此该标准允许 SQL 函数使用不同的语言。大多数定义自己的。 MS-SQL 有 Transact-SQL,PostgreSQL 有 PL/pgSQL。 @Michael 是的,您可以直接使用 SQL。 UPDATE tablename SET column1 = case when p_condition1 then null else column1 end, column2 = case when p_condition2 then null else column2 end, column3 = case when p_condition3 then null else column3 end, WHERE member_id = p_id;

以上是关于为啥在我的 Postgres 函数中使用 IF 语句时出现语法错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的 Postgres 数据库工作了一段时间,然后重新启动后无法“启动服务器”?

为啥我的 IF 在我的 PL?SQL 脚本中被忽略? [复制]

为啥 Postgres 不接受我的计数列?

Laravel:我为啥要使用中间件?

为啥我不能在我的回调中调用我的 vue 组件的函数[关闭]

为啥 SQL 服务器在我的表中插入 0 值而不是使用函数的正确值