我如何在PostgreSQL 8.3查询中声明一个变量?

在MS SQL Server我可以这样做:

DECLARE @myvar INT
SET @myvar = 5

SELECT *
FROM somewhere
WHERE something = @myvar

我如何在PostgreSQL做同样的事情?根据文档,变量被简单地声明为“name type;”,但这给了我一个语法错误:

myvar INTEGER;

谁能给我一个正确语法的例子吗?


当前回答

这取决于你的客户。

然而,如果你正在使用psql客户端,那么你可以使用以下方法:

my_db=> \set myvar 5
my_db=> SELECT :myvar  + 1 AS my_var_plus_1;
 my_var_plus_1 
---------------
             6

如果你使用文本变量,你需要引用。

\set myvar 'sometextvalue'
select * from sometable where name = :'myvar';

其他回答

下面是一个使用PREPARE语句的例子。你仍然不能使用?,但你可以使用$n符号:

PREPARE foo(integer) AS
    SELECT  *
    FROM    somewhere
    WHERE   something = $1;
EXECUTE foo(5);
DEALLOCATE foo;

下面是在postges终端中使用普通变量的代码段。我用过几次。但得想个更好的办法。这里我正在使用字符串变量。使用整型变量时,不需要三引号。三引号在查询时变成单引号;否则就会出现语法错误。在处理字符串变量时,可能有一种方法可以消除对三引号的需求。如果你找到了改进的方法,请及时更新。

\set strainname '''B.1.1.7'''

select *
from covid19strain
where name = :strainname ;

的确,没有明确的方式来声明单值变量,你能做的是

with myVar as (select "any value really")

然后,要访问存储在这个结构中的值,就必须这样做

(select * from myVar)

例如

with var as (select 123)    
... where id = (select * from var)

动态配置设置

你可以“滥用”动态配置设置:

-- choose some prefix that is unlikely to be used by postgres
set session my.vars.id = '1';

select *
from person 
where id = current_setting('my.vars.id')::int;

配置设置始终是varchar值,因此在使用它们时需要将它们转换为正确的数据类型。这适用于任何SQL客户端,而\set只适用于psql

以上要求Postgres 9.2或更高版本。

对于以前的版本,该变量必须在使用之前在postgresql.conf中声明,因此在某种程度上限制了它的可用性。实际上不完全是变量,而是配置“类”,本质上是前缀。但是一旦定义了前缀,任何变量都可以使用而不需要改变postgresql.conf

PostgreSQL中没有这样的特性。您只能在pl/PgSQL(或其他pl/*)中这样做,但不能在纯SQL中这样做。

一个例外是WITH()查询,它可以作为一个变量,甚至是变量的元组。它允许您返回临时值的表。

WITH master_user AS (
    SELECT
      login,
      registration_date
    FROM users
    WHERE ...
)

SELECT *
FROM users
WHERE master_login = (SELECT login
                      FROM master_user)
      AND (SELECT registration_date
           FROM master_user) > ...;