我正在使用postgresql10。我有一个一体式查询,用户可以在其中选择类别样式、事件、区域的非标准组合来搜索构造。请记住,类别样式、事件、区域位于不同的表中。
我想避免多个IFs和JOINs。我还想避免查询计划器为错误的参数组合缓存错误的计划,以及每次查询的后续重新编译。所以我必须使用动态SQL。
要在PostgreSQL中获取动态SQL,我必须使用PL/pgSQL。但是,根据它的文件
要在PL/pgSQL函数中生成动态命令,也就是说,
涉及不同表或不同数据类型的命令
每次他们被处决。PL/pgSQL缓存计划的正常尝试
因为命令在这种情况下不起作用。处理这种事情
问题,提供了EXECUTE语句。而且,没有计划
通过EXECUTE执行命令的缓存。相反,命令是
每次运行语句时总是计划好。如果多行是
返回,只有第一个将被分配给INTO变量-here

直接出现在PL/pgSQL函数中的SQL命令必须引用
每次执行时使用相同的表和列;也就是说,您不能
在SQL命令中使用参数作为表或列的名称。到
绕过这个限制,可以使用
PL/pgSQL EXECUTE语句-以执行新的解析为代价
分析并构建每次执行的新执行计划-here
所以,我想PL/pgSQL不是适合我的案例的工具,因为我有多个表。
我的问题是:PL/pgSQL真的不适合我的情况,还是我遗漏了什么?
子问题:如果不合适,我怎么能为postgreSQL语法动态sql,我找不到任何教程。
谢谢

最佳答案

你能发布一些表定义和一个你想做什么的示例查询吗?我不能百分之百地确定您在追求什么,但是有几种形式的“动态”SQL使用存储过程/函数:
创建一个接受输入参数(即categoryType、styleId、eventName、areaId)并将这些值插入“静态”SQL请求的函数。以下是您的案例的示例查询片段:

SELECT *
FROM category cat
INNER JOIN style st ON cat.styleid = style.id
WHERE (cat.categoryType = pCategoryType OR pCategoryType IS NULL)
AND (st.id = pStyleId OR pStyleId IS NULL)

下面是一个真实的例子:
CREATE OR REPLACE FUNCTION SP_IGLGetItem(
    pItemId INTEGER
)
RETURNS TABLE(
    ItemId INTEGER,
    ItemName VARCHAR(100),
    ItemCategory CHAR(2)
AS
$$
BEGIN
    RETURN QUERY
    SELECT i.ItemId, i.ItemName, i.ItemCategory
    FROM Item i
    WHERE (i.ItemId = pItemId OR pItemId IS NULL) -- Return single item (if specified, otherwise return all)
    ;
END;
$$
LANGUAGE 'plpgsql';

根据不同的条件、参数值等,生成一个包含要动态执行的SQL的字符串。这是尽可能动态的。
根据输入参数的值有条件地运行不同的“静态”SQL语句。
这些和你的情况相符吗?
PL/PGSQL只是用来在Postgres中编写存储过程/函数的语言。如果您确实需要动态SQL生成,那么最好使用PL/PGSQL编写一个函数。
另一种选择是,动态地在客户端应用程序中生成所需的SQL,然后直接提交要执行的SQL。

关于sql - PL/pgSQL用于多合一动态查询,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48216935/

10-16 17:33