我有一个下面运行的PostgreSQL查询。我从如下的shell脚本中调用它
Result=$(psql -U username -d database -t -c
$'SELECT round(sum(i.total), 2) AS "ROUND(sum(i.total), 2)"
FROM invoice i
WHERE i.create_datetime = '2019-03-01 00:00:00-06'
AND i.is_review = '1' AND i.user_id != 60;')
现在,我希望将我硬编码为i.create_datetime = '2019-03-01 00:00:00-06'
的值替换为可变的日期值。
我尝试了两种方法
方式1:
Result=$(psql -U username -d database -t -c
$'WITH var(reviewMonth) as (values(\'$reviewMonth\'))
SELECT round(sum(i.total),2) AS "ROUND(sum(i.total),2)"
FROM var,invoice i
WHERE i.create_datetime = var.reviewMonth::timestamp
AND i.is_review = \'1\' AND i.user_id != 60;')
和
方式2:
Result=$(psql -U username -d database -t -c
$'SELECT round(sum(i.total),2) AS "ROUND(sum(i.total),2)"
FROM invoice i
WHERE i.create_datetime = \'$reviewMonth\'
AND i.is_review = \'1\' AND i.user_id != 60;')
但这两种方式都会引发错误
方式1的抛出错误为:
错误:运算符不存在:带有时区=文本的时间戳
方式2的投掷错误为:
错误:带有时区的时间戳类型“ $ reviewMonth”的无效输入语法
请提出我应该采取的方法。
答案 0 :(得分:0)
您应该尝试使用psql变量。这是一个示例:
# Put the query in a file, with the variable TSTAMP:
> echo "SELECT :'TSTAMP'::timestamp with time zone;" > query.sql
> export TSTAMP='2019-03-01 00:00:00-06'
> RESULT=$(psql -U postgres -t --variable=TSTAMP="$TSTAMP" -f query.sql )
> echo $RESULT
2019-03-01 06:00:00+00
请注意我们如何在查询中设置字符串文字替换的格式::'TSTAMP'
您也可以自己进行替换。这是使用Heredoc的示例:
> export TSTAMP='2019-03-01 00:00:01-06'
> RESULT=$(psql -U postgres -t << EOF
SELECT '$TSTAMP'::timestamp with time zone;
EOF
)
> echo $RESULT
2019-03-01 06:00:01+00
在这种情况下,我们没有使用psql的变量替换,因此我们必须引用变量'$ TSTAMP'。与使用-c相比,使用Heredoc使引用更简单,因为您并没有尝试引用整个命令。
编辑:更多示例,因为看来这还不够清楚。 TSTAMP不必硬编码,它只是一个bash变量,可以像设置任何其他bash变量一样进行设置。
> TSTAMP=$(date -d 'now' +'%Y-%m-01 00:00:00')
> RESULT=$(psql -U postgres -t << EOF
SELECT '$TSTAMP'::timestamp with time zone;
EOF
)
> echo $RESULT
2019-06-01 00:00:00+00
但是,如果您只是在寻找本月初,则根本不需要shell变量
> RESULT=$(psql -U postgres -t << EOF
SELECT date_trunc('month', now());
EOF
)
> echo $RESULT
2019-06-01 00:00:00+00