【问题标题】:Use pl/pgsql variable in calculated columns [duplicate]在计算列中使用 pl/pgsql 变量 [重复]
【发布时间】:2018-08-01 09:24:10
【问题描述】:

我正在为报表构建一个查询,它在计算列中有很多重复的 const 值。简化示例:

select
    c.title || ' corp', -- more than one column appending this
    to_char(c.last_contact, 'YYYY-MM-DD HH24:MI') -- this format is used for other columns as well
from clients c;

我想将那些重复的 const 值提取到变量中并改用变量。在 TSQL 中,我可以使用如下代码实现它:

declare
    @suffix varchar(8) = ' corp',
    @dateFormat varchar(16) = 'YYYY-MM-DD HH24:MI' -- let's pretend that's a correct format string for TSQL

select
    c.title + @suffix,
    convert(varchar(32), c.last_contact, @dateFormat)
from clients c

我正在尝试通过以下方式在 pl/pgsql 中实现相同的行为:

do $$
declare
    suffix text := ' corp';
    date_format text := 'YYYY-MM-DD HH24:MI';
begin
    select
        c.title || suffix,
        to_char(c.last_contact, date_format)
    from clients c;
end;
$$;

它坏了:

ERROR: query has no destination for result data
  Hint: If you want to discard the results of a SELECT, use PERFORM instead.
  Where: PL/pgSQL function inline_code_block line 5 at SQL statement
1 statement failed.

到目前为止,我只找到了在 WHERE 块中使用变量的示例,但在 SELECT 块中没有。

我看过 EXECUTE 'select ...' WITH 的例子,但我快速尝试使用它

do $$
declare
    process_start timestamp := now();
begin
    execute 'select $1;'    
    using process_start;
end;
$$;

只报告DO executed successfully 而不实际选择任何内容。

有没有办法在计算列中使用 pl/pgsql 变量?

在 postgres 中实现此目的的任何其他替代方法?

【问题讨论】:

  • 你想用这个值做什么?您必须将其存储在某个地方。你的例子对我来说没有意义。为什么选择 PL/pgSQL?为什么不在查询中简单地使用now()?
  • @a_horse_with_no_name 我以now() 为例,因为我需要将进程开始日期作为列之一。该过程需要超过一秒钟的时间才能运行,我不希望now() 与查询开始时的值相同。我也有需要附加到某些列的文本常量。
  • 您需要解释根本问题,而不是您认为需要的“解决方案”。另外:now() 在事务期间不会更改:postgresql.org/docs/current/static/…
  • @a_horse_with_no_name 让你澄清now() 的行为。请查看更新后的问题。
  • @a_horse_with_no_name ,你能解释一下stackoverflow.com/questions/1490942/… 是如何回答我的问题的吗?我在声明变量或打印它们的值时没有问题。我在计算列中使用它们时遇到问题。

标签: postgresql plpgsql postgresql-9.5


【解决方案1】:

你想用这个值做什么?令人费解的例子。 使用FUNCTION 或多或少可以这样解决

create or replace function my_function()
returns timestamp as $$
declare
    process_start timestamp := now();
begin
    return process_start;
end;
$$
language plpgsql

如果你真的想忽略代码中唯一选择的结果,你可以使用PERFORM

do $$
declare
    process_start timestamp := now();
begin
    perform (select process_start);
end;
$$;

【讨论】:

  • 我不想忽略它。我更新了问题中的示例代码以更好地说明我的问题。
【解决方案2】:

要在 PL/pgSQL 中使用 SELECT,您必须指定 INTO 子句:

SELECT process_start, s.title || suffix
   INTO var1, var2
   FROM ...

【讨论】:

    猜你喜欢
    • 2017-05-13
    • 2015-06-18
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2015-12-31
    • 2012-09-01
    • 2021-08-29
    相关资源
    最近更新 更多