错误:带有时区的时间戳类型的输入语法无效

abh*_*sek 6 postgresql postgresql-9.3

我有一个 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;')
Run Code Online (Sandbox Code Playgroud)

现在我想要我硬编码的值以i.create_datetime = '2019-03-01 00:00:00-06'将其替换为可变日期值。

我尝试了两种方法

方式一:

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;')
Run Code Online (Sandbox Code Playgroud)

方式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;')
Run Code Online (Sandbox Code Playgroud)

但这两种方式都会抛出错误

方式 1 抛出错误为:

错误:运算符不存在:带有时区的时间戳 = 文本

方式 2 抛出错误为:

错误:带有时区的时间戳类型的输入语法无效:“$reviewMonth”

请建议我的方法应该是什么。

Jer*_*emy 2

您应该尝试使用 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

Run Code Online (Sandbox Code Playgroud)

请注意我们如何格式化查询中的字符串文字替换::'TSTAMP'

您也可以自己进行替换。这是使用定界符的示例:

> 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
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们没有使用 psql 的变量替换,因此我们必须引用像 '$TSTAMP' 这样的变量。使用 Heredoc 使引用比使用 -c 简单得多,因为您不需要尝试引用整个命令。

编辑:更多示例,因为这似乎还不够清楚。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
Run Code Online (Sandbox Code Playgroud)

但是,如果您确实只是查找月初,则根本不需要 shell 变量

> RESULT=$(psql -U postgres -t << EOF
SELECT date_trunc('month', now());
EOF
)
> echo $RESULT
2019-06-01 00:00:00+00
Run Code Online (Sandbox Code Playgroud)