【问题标题】:How to store the select statement output into variable thro PSQL ( postgresql )如何将 select 语句输出存储到变量 thro PSQL ( postgresql )
【发布时间】:2014-02-24 17:00:00
【问题描述】:

我正在探索 Amazon 云环境 (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 。请你帮助我好吗。这将对我当前的项目有很大帮助。

谢谢 基文

【问题讨论】:

  • 使用pl/SQL函数怎么样?

标签: sql postgresql date amazon-redshift


【解决方案1】:

您不能仅在 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 中的单引号加倍。

【讨论】:

    【解决方案2】:

    一个丑陋的把戏是可能的(从 PostgreSQL 9.3 可以得到干净的解决方案)

    postgres=# \set myvar `psql -At postgres -c "select current_date+90;"` postgres=#\设置用户汤姆 postgres=# \设置密码 somepassword postgres=# 创建角色 tom 登录; 创建角色 时间:45.915 毫秒 postgres=# 更改用户:用户密码:'password' 有效直到:'myvar'; 改变角色 时间:8.599 毫秒 postgres=#\杜汤姆 角色列表 角色名称│属性│成员 ────────────┼────────────────────────────────────── ────────┼──────────── tom │ 密码有效期至 2014-05-02 00:00:00+02 │ {}

    现在我不确定 Redshift 中是否提供安全转义的 psql 变量,因为它是 Postgres 的相对较旧的分支。 Craig Ringer 的解决方案可能只有一个并且是正确的。

    【讨论】:

    • 不管远程版本是什么——只要你使用的是最近的psql客户端,我想。所以这应该有效。
    • 这部分应该执行,但是使用 psql 变量作为转义文字可能太新了。
    【解决方案3】:

    最近版本的 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 │
    └─────────────────────┘
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-16
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-09
      相关资源
      最近更新 更多