如何通过PSQL(postgresql)将select语句输出存储到变量中

6qftjkof  于 2023-04-11  发布在  PostgreSQL
关注(0)|答案(3)|浏览(315)

我正在探索亚马逊云环境(Redshift)上的postgresql数据库。我想使用\set命令将值存储到变量中,如下所示。但我无法实现。
我想将“current_date + 90”的输出存储到一个变量中,并在创建用户帐户时将其设置为USER:

postgres=# select current_date;
    date
------------
 2014-01-31
(1 row)

postgres=#
postgres=# select current_date+90;
  ?column?
------------
 2014-05-01
(1 row)

我想休息以上日期如下:

alter user <user_name> with password <new_passowrd> VALID UNTIL 'current_date+90';

---下面是我对回复我的人的回复(他让我用DO $$..)
你好
谢谢你的时间和回复我的帖子。
我在psql提示符中调用.sql文件如下:

psql -h <host_name> -U <user_name> -d <db_name> -p <port> -a -f c:\redshift\scripts\psql-alter-user.sql --log-file c:\testlogs\alter-user.log -v v_username=test_user3 -v v_password='Today123#'

(ii)下面是脚本内容(psql-alter-user.sql)

\echo :v_username
\echo :v_password

\set v_date 'select current_timestamp+90;'
:v_date

alter user :v_username with password :v_password valid until ':v_date';

\q

(iii)执行此脚本后,下面是我的日志文件:

********* QUERY **********
select current_timestamp+90;
**************************

           ?column?            
-------------------------------
 2014-05-01 23:40:47.856804+00
(1 row)

********* QUERY **********
alter user test_user3 with password 'Today123#' valid until ':v_date';
**************************

我无法在ALTER USER语法中将实际值(2014-05-01 23:40:47.856804+00)作为:v_date。请帮助我。这将在我当前的项目中帮助我很多。
谢谢Keavan

nhaq1z21

nhaq1z211#

你不能在Redshift中做这件事,因为在PostgreSQL中做这件事的唯一方法是在PL/PgSQL函数或DO块中使用动态SQL -EXECUTE。你在Redshift中没有PL/pgSQL。
您必须做的是让客户端脚本读取current_timestamp+90的值,将其存储在一个变量中,并根据结果生成发送到服务器的ALTER语句。
如果你要这样做,为什么不让客户端生成到期时间,而不是问服务器呢?如果你使用shell脚本,例如:

password="fr'ed"
expires=`date -I -d '+ 90 days'`
psql -c "alter user test_user3 with password '${password//\'/''}' valid until '${expires} 00:00:00';"

注意$password中的双引号。

hivapdat

hivapdat2#

一个丑陋的技巧是可能的(干净的解决方案是从PostgreSQL 9.3)

postgres=# \set myvar `psql -At postgres -c "select current_date+90;"`
postgres=# \set user tom
postgres=# \set password somepassword

postgres=# create role tom login;
CREATE ROLE
Time: 45.915 ms
postgres=# alter user :user with password :'password' valid until :'myvar';
ALTER ROLE
Time: 8.599 ms

postgres=# \du tom
                            List of roles
 Role name │                 Attributes                  │ Member of 
───────────┼─────────────────────────────────────────────┼───────────
 tom       │ Password valid until 2014-05-02 00:00:00+02 │ {}

现在我不确定,如果安全转义的psql变量在Redshift中可用,因为它是Postgres的相对旧的分支。克雷格Ringer解决方案可能只有一个并且正确。

xkftehaa

xkftehaa3#

最近版本的PSQL有\gset元命令,可以很好地处理这个问题。
Postgres current version psql documentation

\set :v_username tom
\echo :v_username
-- tom

-- notice the lack of a ';'
select current_date + 90 v_date  \gset 

\echo :v_date
-- 2019-05-22

alter user :user valid until :'v_date';

我发现这对于在.psqlrc文件中作为变量存储的轻量级过程非常方便。
请注意,尽管日期作为字符串在alter user语句中可以工作,但在更通用的查询中使用日期函数通常需要显式转换为::date,例如:

select date_trunc('year',:v_date);
-- ERROR:  function date_trunc("unknown", integer) does not exist

select date_trunc('year',:'v_date'::date);
┌─────────────────────┐
│     date_trunc      │
├─────────────────────┤
│ 2019-01-01 00:00:00 │
└─────────────────────┘

相关问题