问题描述
超级棘手的问题。我有一个客户想要基于表示true/false
的字符串语句输出rule
。
例如如果规则是字符串:"56 AND 78"
,则表示“如果true
具有ID为Table A
和ID为56
的行,则返回78
。请注意,它没有并不是说同一行的ID为56
和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的方法。
建议将不胜感激!
解决方法
听起来您的sentences
遵循以下规则:
- 数字是一个小整数。
- 一个术语可以是单个数字,也可以是一组术语,或者在每对之间使用AND或在每对之间使用OR。
- 术语必须用括号括起来才能与更多术语组合。
如果是这种情况,那么我认为您可以:
- 将每个数字替换为
(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转换来说不是必需的。
您可以通过这种方式
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。