我正在亚马逊云环境(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';
**************************
我无法将实际值(2014-05-01 23:40:47.856804 + 00)作为:ALTER USER语法中的v_date。请你帮助我好吗。这对我目前的项目有很大帮助。
谢谢 Keavan
答案 0 :(得分:1)
你不能完全在Redshift中这样做,因为在PostgreSQL中实现它的唯一方法是在EXECUTE
函数或PL/PgSQL
块中使用动态SQL - DO
。你没有在Redshift中使用PL / pgSQL。
您必须做的是让客户端脚本读取current_timestamp+90
的值,将其存储在变量中,并从结果生成它发送给服务器的ALTER
语句。 / p>
如果您要这样做,为什么不让客户端生成到期时间,而不是询问服务器?如果您使用的是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
中单引号加倍。
答案 1 :(得分:1)
可能有一个丑陋的技巧(可从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 │ {}
现在我不确定,如果Redshift中有安全转义的psql变量,因为它是Postgres的相对较旧的分支。克雷格林格解决方案可能只有一个并且是正确的。
答案 2 :(得分:0)
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 │
└─────────────────────┘