【问题标题】:Is there an alternative to `SELECT INTO` within an `IF EXISTS (...)`?在“IF EXISTS (...)”中是否有“SELECT INTO”的替代方法?
【发布时间】:2020-02-20 17:12:19
【问题描述】:

所以我正在尝试编写完整性检查。

Foos 有 Tops 和 Alpha x 或 Beta。

Top、Alpha 和 Beta 都引用 Gamma 以及 Alpha 或 Beta 和 Foo 必须引用相同的 Gamma 作为其 Top。

即

foo1 --> top1 --> gamma1
foo1 --> alpha1 --> gamma1

允许,

foo1 --> top1 --> gamma1
foo1 --> alpha1 --> gamma2

禁止

我一直在努力

DO $check$
DECLARE
   violation_type TEXT;
BEGIN
   IF EXISTS(
       SELECT CASE WHEN alpha.id IS NOT NULL THEN 'alpha' ELSE 'beta' END INTO violation_type
       FROM
           Foo o
           LEFT JOIN top t ON o.top_id = t.id
           LEFT JOIN alpha a ON o.alpha_id = a.id
           LEFT JOIN beta b ON o.beta_id = b.id
       WHERE
           t.gamma_id <> coalesce(a.gamma_id, b.gamma_id)
   )THEN
       RAISE EXCEPTION 'Foo Violation: There are %-type foos whose top references a different gamma', violation_type;
   END IF;
END $check$;

但这失败了,因为

错误:此处不允许 SELECT ... INTO

这很遗憾,因为我非常希望不必复制此代码,只需检查一次 Alpha 和一次 Beta。

这里有没有可以使用的替代方案,还是我被两个检查卡住了?

【问题讨论】:

  • 。 .样本数据比抽象更有帮助。
  • 在 foo 中存储 gamma 并使用复合外键关系。
  • @GordonLinoff 没有复合外键。我们刚刚花了几周时间来解开一个数据库模型 s.t.我们可以摆脱这个。
  • 你不需要 Select INTO :: EXISTS(...) 会产生一个布尔值,它可以是 IF() (如果允许 if)或 WHERE(...) (如果不允许)内的条件)

标签: sql postgresql stored-procedures plpgsql postgresql-9.6


【解决方案1】:

您不能在 EXISTS 子查询中使用 SELECT INTO。 The manual:

子查询通常只会执行足够长的时间来确定是否至少返回了一行,而不是一直到完成。

改为使用SELECT INTO 并在下一步中使用IF FOUND ... 检查:

DO
$check$
DECLARE
   violation_type TEXT;
BEGIN
   SELECT INTO violation_type
   CASE   WHEN f.alpha.id IS NOT NULL THEN 'alpha' ELSE 'beta' END
   FROM   foo        f
   JOIN   top        t ON t.id = f.top_id
   LEFT   JOIN alpha a ON a.id = f.alpha_id
   LEFT   JOIN beta  b ON b.id = f.beta_id
   WHERE  t.gamma_id <> coalesce(a.gamma_id, b.gamma_id);

   -- IF violation_type IS NOT NULL THEN  -- alternative
   IF FOUND THEN
      RAISE EXCEPTION 'Foo Violation: There are %-type foos whose top references a different gamma', violation_type;
   END IF;
END
$check$;

或者,您可以检查变量是否已分配,如注释所示。

【讨论】:

    猜你喜欢
    • 2019-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 2012-02-14
    • 2021-07-06
    • 1970-01-01
    • 2010-09-20
    相关资源
    最近更新 更多