[英]Postgresql function with table as input? Is dynamic SQL in a plpgsql function the way to go?
I have a common situation that comes up where I want to join with a table moredata. 我有一个常见的情况出现在我想加入表moredata的地方。 To give the simplest example, imagine I have:
举一个最简单的例子,假设我有:
SELECT *
FROM x
JOIN moredata d on x.yyyymmdd = d.yyyymmdd
x
will vary while moredata
stays the same. x
会有所不同,而moredata
保持不变。 What's a good way stylistically to reuse code, automate the above so that I can apply it to different tables (eg. do the same thing on table 'y' instead of 'x')? 风格上重用代码的好方法是什么,自动化上面的代码以便我可以将它应用到不同的表中(例如,在表'y'而不是'x'上做同样的事情)?
One way would be to write a plpgsql function using dynamic SQL that operates on the name of the table. 一种方法是使用动态SQL编写plpgsql函数,该函数对表的名称进行操作。 Something like:
就像是:
CREATE FUNCTION joinmoredata(tblname text) RETURNS TABLE(...) AS $$
BEGIN
RETURN QUERY EXECUTE format('SELECT * FROM %I JOIN moredata on ...', tblname);
END;
$$ LANGUAGE plpgsql;
But then you couldn't apply it to a derived table or a CTE. 但是,您无法将其应用于派生表或CTE。 Is there a better way?
有没有更好的办法? Or is dynamic SQL the best way to reuse code in this situation?
或者动态SQL是在这种情况下重用代码的最佳方法?
(Note, the actual query is a lot more complicated than SELECT * FROM x JOIN moredata d on x.yyyymmdd = d.yyyymmdd
which is why I want to reuse code.) (注意,实际查询要比
SELECT * FROM x JOIN moredata d on x.yyyymmdd = d.yyyymmdd
复杂得多,这就是我想重用代码的原因。)
As long as you use the same column names with the same data types from each table in place of x
and return the same row type, that's a good candidate for dynamic SQL. 只要在每个表中使用相同的列名和相同的数据类型代替
x
并返回相同的行类型,那么它就是动态SQL的理想选择。 Exactly like you already have in your question. 完全像你已经在你的问题中。 Your use of
format()
with %I
suggests you are aware of how to sanitize identifiers avoid syntax errors and SQL injection. 您对
%I
的format()
使用表明您知道如何清理标识符以避免语法错误和SQL注入。
You need to have a plan for privilege management. 您需要有一个特权管理计划。 And I would pass schema-qualified table names or data type
regclass
to avoid confusion with table name resolution and possibly other tables with the same name in a different schema. 我会传递模式限定的表名或数据类型
regclass
以避免混淆表名解析和可能在不同模式中具有相同名称的其他表。
Closely related, with more details: 密切相关,有更多细节:
If it gets more complicated - varying column names and types - you can always concatenate query strings in a client program ... 如果它变得更复杂 - 变化的列名和类型 - 你总是可以在客户端程序中连接查询字符串......
I can only say that I use dynamic SQL any time I need to reuse bigger parts of SQL code and change only something in WHERE clause or table names etc. And it works OK and I do this way also very complicated CTE queries containing also INSERTs or UPDATESs and it works. 我只能说我在任何时候都需要重用SQL代码的更大部分并且只改变WHERE子句或表名等中的某些东西时使用动态SQL。它工作正常我也这样做也很复杂的CTE查询也包含INSERT或更新,它的工作原理。 So I would vote for dynamic SQL.
所以我会投票支持动态SQL。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.