【问题标题】:Dynamically Generate SQL for Logical Sentence为逻辑句动态生成 SQL
【发布时间】:2020-08-25 14:34:56
【问题描述】:

超级棘手的问题。我有一个客户想要根据代表rule 的字符串句子输出true/false

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

现在,我可以继续为简单的情况动态生成一些伪 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)" 用英语翻译为“表 A 是否有一行具有来自前三个 ID 之一的(任何)ID 和来自后三个 ID 的(任何)一个?”

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

建议将不胜感激!

【问题讨论】:

  • 我觉得你的解释很混乱。首先你告诉我们我们应该将 AND 解释为 OR,因为一行不能同时有两个不同的 ID,然后你说 AND 应该被解释为“AND”来检查一行是否有不同的行?如果 AND 始终是 OR,则复杂语句简化为 ID 列表,所有内容都只是要检查的数字列表:(43, 44, 47, 2182, 2179, 2183)
  • 你必须为你的句子设置一些基本规则。 IE。标签,关键字,它们意味着一件事,而且只有一件事。上下文解析将是可怕的,并且是不明智的。你可以在 SQL 周围做一层绒毛,但你必须让它尽可能严格,或者准备编写大量的解析代码。
  • 您使用的是什么 DBMS(即什么版本的 SQL)?
  • 您的逻辑可能有误 - 您的语句“如果表 A 有 ID 为 56 的行或 ID 为 78 的行则返回真”与解释冲突。您可能需要“如果表 A 有 ID 为 56 的行和 ID 为 78 的其他行,则返回 true”。当然这不会让你的解析变得更容易。
  • @SørenKongstad 我很抱歉,我想出了一个更清晰的方式来描述这个问题。查看更新的问题。

标签: sql dynamic-programming dynamic-sql postgresql-11


【解决方案1】:

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

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

如果是这样的话,我想你可以简单地:

  • (SELECT EXISTS(SELECT 1 FROM table_a WHERE id = *number*))替换每个数字
  • 将所有括号、AND 和 OR 留在原处。
  • 将字符串括在另一组括号中,并添加前缀RETURN QUERY

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

如果你想进一步优化,可以将(5 or 6 or 7)切换为(SELECT 1 FROM table_a WHERE id IN (5,6,7))。但这对于正确的 SQL 翻译来说不是必要的

【讨论】:

    【解决方案2】:

    你可以这样做

      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;
    

    终于返回order_rec。 欲了解更多信息,您可以here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-26
      • 2021-07-10
      • 1970-01-01
      相关资源
      最近更新 更多