警告当PostgreSQL存储过程返回一个带有不正确列顺序的table结果集。

huangapple go评论53阅读模式
英文:

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

这是问题的一个示例

https://dbfiddle.uk/AzJ5gPa7

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

https://dbfiddle.uk/AzJ5gPa7

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.

huangapple
  • 本文由 发表于 2023年7月13日 12:50:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/76676029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定