为逻辑语句动态生成 SQL

Dynamically Generate SQL for Logical Sentence

超级棘手的问题。我有一个客户想要根据表示 rule.

的字符串句子输出 true/false

例如如果规则是字符串:"56 AND 78",则这意味着“Return true 如果 Table A 具有 ID 56 和 ID 78 的行。请注意,这并不意味着同一行具有 ID 5678,因为那是不可能的。

现在,我可以继续为简单情况动态生成一些伪 SQL,如下所示:

RETURN QUERY (SELECT EXISTS(SELECT 1
                            FROM table_a
                            WHERE id = 56)
              AND
              SELECT EXISTS(SELECT 1
                            FROM table_a
                            WHERE id = 78))

其中 WHERE 子句直接从 rule 生成。这样就满足简单句了

但是,规则可能会复杂得多。
例如。 "(43 OR 44 OR 47) AND (2182 OR 2179 OR 2183)" 用英语翻译为“Does Table A 有一行具有来自前三个 ID 之一的(任何)ID 和来自后三个 ID 的(任何)ID?”

随着 sentence 变得越来越复杂,我正在努力寻找一种动态生成 SQL 的方法。

建议将不胜感激!

你可以这样做

  EXECUTE  IMMEDIATE 'SELECT CASE WHEN EXISTS(SELECT 1
                        FROM table_a
                        WHERE id = :ID1 OR id = :ID2) THEN 1 ELSE 0 END'   
            INTO  order_rec
             USING  56, 78;

终于 return order_rec。 如需更多信息,您可以 here.

听起来您的 sentences 遵循以下规则:

  1. 数字是一个小整数。
  2. 术语可以是单个数字,也可以是一组术语,每对之间使用 AND,或者每对之间使用 OR。
  3. 术语必须用括号括起来,以便与更多术语组合。

如果是这种情况,那么我想你可以简单地:

  • 将每个数字替换为 (SELECT EXISTS(SELECT 1 FROM table_a WHERE id = *number*))
  • 将所有括号、AND 和 OR 保留在原处。
  • 再用一组括号和前缀 RETURN QUERY.
  • 将字符串括起来

这肯定不会是表达您的 最简单的 SQL sentence 但我认为它是等效的。

如果想优化更多,可以把(5 or 6 or 7)换成(SELECT 1 FROM table_a WHERE id IN (5,6,7))。但对于正确的 SQL 翻译,这不应该是 必需的