Postgresql 错误:带时区的时间戳类型的输入语法无效
我有一个PostgreSQL查询,如下所示,运行良好。我从shell脚本调用它,如下所示Postgresql 错误:带时区的时间戳类型的输入语法无效,postgresql,postgresql-9.3,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
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”的时间戳类型的输入语法无效
请建议我的方法。您应该尝试使用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
>导出TSTAMP='2019-03-01 00:00:01-06'
>结果=$(psql-U postgres-t echo$结果
2019-03-01 06:00:01+00
在本例中,我们没有使用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
>TSTAMP=$(日期-d'现在'+%Y-%m-01 00:00:00')
>结果=$(psql-U postgres-t echo$结果
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
>RESULT=$(psql-U postgres-t echo$RESULT
2019-06-01 00:00:00+00
它是postgresql还是mysql?@nacho它是postgresql所以不要将它标记为mysql我不认为这样对我有帮助。我的reviewMonth为reviewMonth=$(日期-d'now'+'%Y-%m-01 00:00:00')现在,我想将此reviewMonth值用作i.create_datetime=reviewMonth值此方法对您来说应该很好。上面的第二个方法由于引用问题而失败。我将向您展示如何解决这些问题。您在执行导出TSTAMP时对值进行了硬编码。在我的情况下,它不能硬编码为“2019-03-01 00:00:01-06”此值来自reviewMonth=$(日期-d'now'+%Y-%m-01 00:00:00')更详细地说,想象一个场景,我有一个postgresql查询1,它提供了100行不同的Id。现在对于所有不同的Id,我必须使用while read Id运行查询2;do query 2。在查询2中,现在如何动态使用Id,该Id必须从变量IdFor one中动态读取值,这种技术在这两种情况下都有效。导出不必硬编码,它可以像任何其他bash变量一样设置。其次,对于您提到的两种情况,最好在postgres中完成所有工作,而不涉及shell变量。@abhisek我又添加了几个示例。