to_date
可以将字符串转换为日期:
select to_date('2024-01-01','YYYY-MM-DD');
to_date
------------
2024-01-01
(1 row)
让我们检查一下数据类型:
select pg_typeof(to_date('2024-01-01','YYYY-MM-DD'));
pg_typeof
-----------
date
为什么不能将变量设置为日期类型?
\set mydate to_date('2024-01-01','YYYY-MM-DD')
select :mydate;
ERROR: column "yyyy" does not exist
LINE 1: select to_date(2024-01-01,YYYY-MM-DD);
^
Time: 0.212 ms
你必须使用
\gset
来实现:
SELECT to_date('2024-01-01','YYYY-MM-DD') AS mydate \gset
SELECT :mydate;
?column?
══════════
2022
(1 row)
SELECT :'mydate';
?column?
════════════
2024-01-01
(1 row)
\gset
使用列别名作为变量名,并将查询结果赋给该变量。
替换后的第一个查询如下所示:
SELECT 2024-01-01;
所以将其视为数字,结果是2022。
第二个查询将变量转义为字符串文字并生成所需的结果。
\set
命令不是 PostgreSQL 本身的一部分,而是 psql
命令行实用程序的一个功能。 文档中的相关部分包括:
psql 提供类似于常见 Unix 命令 shell 的变量替换功能。变量只是名称/值对,其中值可以是任何长度的任何字符串。
所以,这个系统中不存在“日期变量”这样的东西。元命令
\set mydate to_date('2024-01-01','YYYY-MM-DD')
将一个 字符串值 分配给名为 mydate
的变量。然后,当您使用 :mydate
时,该字符串将被简单地“逐字插入”到要运行的 SQL 中的该位置。
你可能认为这仍然没问题,因为结果是运行这个:
select to_date('2024-01-01','YYYY-MM-DD');
但实际发生的情况是,
\set
元命令对单引号进行了特殊处理,因此变量中最终的结果是
to_date(2024-01-01, YYYY-MM-DD)
,而您尝试运行的SQL是这样的:
select to_date(2024-01-01,YYYY-MM-DD);
这解释了错误 - 2024-01-01
是一个有效的表达式,一种有趣的书写方式 2022
;但是
YYYY
没有任何引号看起来像一个列名称。
因此,如果您确实想在这种情况下使用字符串插值功能,则需要转义引号。我还没有测试过,但我想它看起来像这样:
\set mydate 'to_date(\'2024-01-01\',\'YYYY-MM-DD\')'
但是,请记住,这
并不是将日期存储在变量中,它只是保存一个字符串以“复制并粘贴”到将来的查询中。