【问题标题】:PostgreSQL GOTO like keyword to jump to a blockPostgreSQL GOTO like 关键字跳转到一个块
【发布时间】:2012-11-22 08:03:36
【问题描述】:

我有一个 PostgreSQL 函数

CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
BEGIN
IF i<0 THEN 
RETURN i + 1;
ELSE
  GOTO label1;
END IF
<<label1>>
RETURN null;
END;
$$ LANGUAGE plpgsql;

在这个函数中,我必须 GOTO 到 label1,但是 GOTO 关键字不起作用,你能帮我找到从特定代码跳转到标签的方法吗?

【问题讨论】:

  • 为什么需要 ELSE 分支?您的 IF 分支从函数返回,而您的 ELSE 只是说“转到 IF/ELSE 之后的下一条语句”,无论如何它都会这样做。

标签: postgresql plpgsql


【解决方案1】:

另一个嵌套的 Begin 块?

BEGIN
  <<label1>>
  BEGIN 
      IF i<0 THEN 
          RETURN i + 1;
      ELSE
          EXIT label1;
      END IF;
  END;
  RETURN null;
END;

【讨论】:

  • 谢谢。在我的情况下,它似乎工作得很好。
  • 这非常适合 (IF) 保护子句。
【解决方案2】:

解决方法:

<<label>>
LOOP
   ...
   EXIT label WHEN i > 0;
   ...
   EXIT;
 END LOOP label;
 some;

但我十年没用过 - 所以通常你会做错事

【讨论】:

  • JUMPing 是汇编语言中的基本语句。并且您所有的 IF 或 CASE 都在幕后转换为 GOTO。高层人士对 GOTO 的厌恶来自于不了解计算机科学的基础知识。
  • @Nulik - 对 GOTO 的厌恶让计算机科学家对 Fortran、Cobol、Basic 中的问题做出了反应。由于宗教原因,GOTO 没有在 Postgres 中实现——基于 AST 的解释的设计不允许这样做。 PL/pgSQL 基于快速 AST 解释(不需要 JIT),但 GOTO 很难实现。 PCode 解释允许简单的 GOTO 实现(它就像便携式汇编程序),但需要 JIT,并且代码很多且复杂度更高。
【解决方案3】:

PL/PgSQL 没有 GOTO 运算符。

但是,为什么需要 goto?在您的情况下,您可以简单地删除 ELSE 并获得您正在寻找的行为。

【讨论】:

  • 我知道 GOTO 在 Postgresql 中不起作用。我有一段代码要在特定条件下跳过,因为我必须使用 GOTO 之类的东西。
【解决方案4】:

你不需要GOTO

DECLARE 一个布尔变量。根据您是否要执行下一个块来设置其值。将该块包装在一个测试变量的IF 中。魔法,跳过了!

我假设您的代码已被缩减和简化,否则将毫无意义。这是一种方法,假设您不能只删除“ELSE ... GOTO”并让控制继续进行。

CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
DECLARE
    run_condition boolean = 't';
BEGIN
  IF i<0 THEN
    RETURN i + 1;
  ELSE
    run_condition = 'f';
  END IF;
  IF run_condition THEN
    -- Do the optional thing
  END;
  RETURN null;
END;
$$ LANGUAGE plpgsql;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 1970-01-01
    • 1970-01-01
    • 2020-06-04
    • 2021-10-12
    • 1970-01-01
    相关资源
    最近更新 更多