英文:
Warn when a postgres procedure is returning a setof table result with an incorrect column order
问题
If procedure is defined to return a setof table type, what can I do to ensure that columns from the procedure are being returned in the correct order.
如果过程定义为返回一组表类型,我可以采取什么措施来确保从过程返回的列按正确顺序返回。
Here is an example of the problem
这是问题的一个示例
The following function makes an assumption about the column order in the return table type of business_user_group
以下函数对business_user_group
的返回表类型的列顺序进行了假设
create or replace function organisation_groups(
organisation_id varchar
) returns setof business_user_group as $$
select
business_user_group.organisation_id,
business_user_group.group_id,
business_user_group.business_user_id
from business_user_group
where business_user_group.organisation_id = organisation_groups.organisation_id;
$$ language sql stable;
If the column order is different for the table type business_user_group
between deployed environments this becomes a real footgun.
如果在部署的环境中,表类型business_user_group
的列顺序不同,那么这将成为一个真正的问题。
DB diffing tools often miss column order, which doesn't help matters here.
数据库差异比较工具通常会忽略列的顺序,这并不有助于解决问题。
What can be done to prevent this?
有什么方法可以防止这种情况发生?
英文:
If procedure is defined to return a setof table type, what can I do to ensure that columns from the procedure are being returned in the correct order.
Here is an example of the problem
The following function makes an assumption about the column order in the return table type of business_user_group
create or replace function organisation_groups(
organisation_id varchar
) returns setof business_user_group as $$
select
business_user_group.organisation_id,
business_user_group.group_id,
business_user_group.business_user_id
from business_user_group
where business_user_group.organisation_id = organisation_groups.organisation_id;
$$ language sql stable;
If the column order is different for the table type business_user_group
between deployed environments this becomes a real footgun.
DB diffing tools often miss column order, which doesn't help matters here.
What can be done to prevent this ?
答案1
得分: 2
问题出在查询中的选择列表上。在 PL/pgSQL 过程中选择变量列表时,通常建议明确列举列,而不是使用 SELECT *
。除非出现程序员错误,列举列可以确保选择列表与变量的顺序与表中的列顺序兼容。
您的情况需要相反的方法;即,使用 SELECT *
以确保返回的数据与表的列顺序一致。因为与表关联的类型和 SELECT *
的列顺序都完全依赖于表的列顺序,所以可以保证它们的顺序会匹配。这种方法还可以减少在添加、删除或重命名列时所需的代码维护量。
在 PL/pgSQL 过程中,当查询选择到声明为表行类型的变量时,应优先考虑使用 SELECT *
方法。
英文:
The problem is with the select list in the query. When selecting into a list of variables in a PL/pgSQL procedure, the general recommendation is to explicitly enumerate the columns instead of using SELECT *
. Barring programmer error, enumerating the columns ensures that the order is compatible between the select list and the variables regardless of column order in the table.
Your situation requires the opposite approach; i.e., use SELECT *
to ensure that the returned data is consistent with the table's column order. Because the column order for both the type associated with the table and SELECT *
are fully dependent on the table's column order, it is guaranteed that the order will match. This approach also reduces the amount of code maintenance required when columns are added, dropped, or renamed.
In a PL/pgSQL procedure when a query selects into a variable declared as the row type of the table, then the SELECT *
approach should also be preferred.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论