了解 PLPGSQL 基础知识

发布于 2025-01-13 19:27:16 字数 1561 浏览 4 评论 0原文

我在那里,我是 PL/pgSQL 的新手,我正在从事的项目开始使用它进行一些数据密集型处理实现,我无法理解一些基本基础,甚至一次又一次地查看文档

所以我有一个函数看起来像这样:

CREATE OR REPLACE FUNCTION sum_stuff_over_value(
       param1 uuid,
       param2 uuid,
       param3 enum
        )
      RETURNS float AS
      $$
      DECLARE
        table_name varchar;
        column_name varchar;
        resolution integer;
        another_table varchar := 'name_of_another_table';
        another_column varchar := 'name_of_another_column';
        sum float;

  BEGIN
    -- Get data from another table fiven a param2 ID
    SELECT * INTO table_name, column_name, esolution
    FROM get_table_and_column_by_Id(param2, param3);

    -- Sum table column over region
    EXECUTE format(
        'SELECT sum(grid_mat.%I * grid_def.%I)
            FROM
                get_uncompact_region($1, $2) region
                INNER JOIN %I grid_mat ON grid_mat.index = region.index
                INNER JOIN %I grid_def ON grid_def.index = region.index;
        ', column_name, another_column, table_name, another_table)
        USING param1, resolution
        INTO sum;
    RETURN sum;
  END;
$$
LANGUAGE plpgsql;

我想说我相当了解非常非常基本的流程,实例化变量,其中一些被分配等等...

我最困难的是理解哪个值包含 %I,以及如何在这里

INNER JOIN %I grid_mat ON grid_mat.index = region.index
INNER JOIN %I grid_def ON grid_def.index = region.index;

%I 持有(我相信)不同的值来连接不同的表,

我试图通过提出打印值的通知来解决这个问题,但我无法让它工作。我正在尝试添加一些断点来调试数据库中隔离的断点,但由于它对我来说是新的,所以并不简单

任何人都可以帮助我理解这里发生了什么吗?

预先非常感谢

I there, I am new to PL/pgSQL, the project I am working on started using it for some data-intensive handling implementations, I am failing to understand some basic foundations, even reviewing the docs again and again

So I have a function that looks like this:

CREATE OR REPLACE FUNCTION sum_stuff_over_value(
       param1 uuid,
       param2 uuid,
       param3 enum
        )
      RETURNS float AS
      $
      DECLARE
        table_name varchar;
        column_name varchar;
        resolution integer;
        another_table varchar := 'name_of_another_table';
        another_column varchar := 'name_of_another_column';
        sum float;

  BEGIN
    -- Get data from another table fiven a param2 ID
    SELECT * INTO table_name, column_name, esolution
    FROM get_table_and_column_by_Id(param2, param3);

    -- Sum table column over region
    EXECUTE format(
        'SELECT sum(grid_mat.%I * grid_def.%I)
            FROM
                get_uncompact_region($1, $2) region
                INNER JOIN %I grid_mat ON grid_mat.index = region.index
                INNER JOIN %I grid_def ON grid_def.index = region.index;
        ', column_name, another_column, table_name, another_table)
        USING param1, resolution
        INTO sum;
    RETURN sum;
  END;
$
LANGUAGE plpgsql;

I'd say I fairly understand the very very basic flow, instantiate vars, some of them assigned, etc...

What I am struggling the most is understanding which value holds %I, and how here

INNER JOIN %I grid_mat ON grid_mat.index = region.index
INNER JOIN %I grid_def ON grid_def.index = region.index;

%I is holding (I believe) different values to join different tables

I tried to figure it out by raising notices to print values, but I couldn't make it work. I am trying to add some breakpoints to debug this isolated in the DB but as it's new to me is not being straightforward

Can anyone help me understand what is going on here?

Thanks a lot in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晨敛清荷 2025-01-20 19:27:16

您应该阅读format的文档。第一个 %I 将被替换为 format 的第二个参数的值 (column_name),转义为标识符,第二个 >%I 将被替换为 another_column 的值,依此类推。

You should read the documentation of format. The first %I will be replaced by the value of the second argument of format (column_name), escaped as an identifier, the second %I will be replaced by the value of another_column, and so on.

烂柯人 2025-01-20 19:27:16

来自 https://www.postgresql.org /docs/14/plpgsql-statements.html#PLPGSQL-STATMENTS-SQL-ONEROW
围绕部分:示例 43.1。在动态查询中引用值
引用:

动态 SQL 语句也可以使用 format 函数安全地构造(参见第 9.4.1 节)。例如:

执行格式('UPDATE tbl SET %I = %L '
   'WHERE key = %L', colname, newvalue, keyvalue);

第 9.4.1 节链接:
https://www.postgresql.org/docs/ 14/functions-string.html#FUNCTIONS-STRING-FORMAT
引自第 9.4.1 节

type(必需)用于生成的格式转换的类型
格式说明符的输出。支持以下类型:

s 将参数值格式化为简单字符串。空值是
被视为空字符串。

I 将参数值视为 SQL 标识符,如果满足以下条件,则将其用双引号括起来
必要的。值为 null 时会出错(相当于
quote_ident)。

L 将参数值引用为 SQL 文字。空值是
显示为字符串 NULL,不带引号(相当于
quote_nullable)。
有几个例子,引用:

SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
Result: INSERT INTO "Foo bar" VALUES('O''Reilly')

最后解释一下:
您的EXECUTE格式字符串有4个%I。然后
第一个 %I 引用 column_name
第二个 %I 引用 another_column
第三个 %I 引用 table_name
第四个 %I 引用 another_table

FROM https://www.postgresql.org/docs/14/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW.
around section: Example 43.1. Quoting Values in Dynamic Queries
quote:

Dynamic SQL statements can also be safely constructed using the format function (see Section 9.4.1). For example:

EXECUTE format('UPDATE tbl SET %I = %L '
   'WHERE key = %L', colname, newvalue, keyvalue);

Section 9.4.1 LINK: :
https://www.postgresql.org/docs/14/functions-string.html#FUNCTIONS-STRING-FORMAT
Quote from Section 9.4.1

type (required) The type of format conversion to use to produce the
format specifier's output. The following types are supported:

s formats the argument value as a simple string. A null value is
treated as an empty string.

I treats the argument value as an SQL identifier, double-quoting it if
necessary. It is an error for the value to be null (equivalent to
quote_ident).

L quotes the argument value as an SQL literal. A null value is
displayed as the string NULL, without quotes (equivalent to
quote_nullable).
There have serval examples, quote:

SELECT format('INSERT INTO %I VALUES(%L)', 'Foo bar', E'O\'Reilly');
Result: INSERT INTO "Foo bar" VALUES('O''Reilly')

Finally explain:
your EXECUTE format string have 4 %I. Then
1st %I refer to column_name
2nd %I refer to another_column
3rd %I refer to table_name
4th %I refer to another_table

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文