如何在PostgreSQL查询中声明变量

时间:2009-09-29 06:41:06

标签: sql postgresql postgresql-8.3

如何声明变量以用于PostgreSQL 8.3查询?

在MS SQL Server中我可以这样做:

DECLARE @myvar INT
SET @myvar = 5

SELECT *
FROM somewhere
WHERE something = @myvar

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

myvar INTEGER;

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

11 个答案:

答案 0 :(得分:169)

我使用WITH clause完成了同样的目标,它远不如优雅,但可以做同样的事情。虽然这个例子真的有点过分。我也不特别推荐这个。

WITH myconstants (var1, var2) as (
   values (5, 'foo')
)
SELECT *
FROM somewhere, myconstants
WHERE something = var1
   OR something_else = var2;

答案 1 :(得分:81)

PostgreSQL中没有这样的功能。您只能在pl / PgSQL(或其他pl / *)中执行此操作,但不能在纯SQL中执行此操作。

异常是WITH ()查询,它可以作为变量,甚至tuple个变量。它允许您返回临时值表。

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) > ...;

答案 2 :(得分:41)

这取决于您的客户。

但是,如果您使用的是 psql 客户端,则可以使用以下内容:

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

答案 3 :(得分:38)

动态配置设置

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

-- choose some prefix that is unlikey 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

答案 4 :(得分:19)

使用pl / PgSQL

之外的临时表

除了建议使用pl / pgsql或其他pl / *语言之外,这是我能想到的唯一其他可能性。

begin;
select 5::int as var into temp table myvar;
select *
  from somewhere s, myvar v
 where s.something = v.var;
commit;

答案 5 :(得分:9)

我想对@DarioBarrionuevo's answer提出改进建议,以便更简单地利用临时表。

DO $$
    DECLARE myvar integer = 5;
BEGIN
    CREATE TEMP TABLE tmp_table ON COMMIT DROP AS
        -- put here your query with variables:
        SELECT * 
        FROM yourtable
        WHERE id = myvar;
END $$;

SELECT * FROM tmp_table;

答案 6 :(得分:5)

以下是使用PREPARE statements的示例。您仍然无法使用?,但可以使用$n表示法:

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

答案 7 :(得分:2)

此解决方案基于fei0x提出的解决方案,但是它的优点是无需在查询中加入常量的值列表,并且可以在查询开始时轻松列出常量。它也适用于递归查询。

基本上,每个常量都是在WITH子句中声明的单值表,然后可以在查询其余部分的任何位置调用该表。

  • 带有两个常量的基本示例:
WITH
    constant_1_str AS (VALUES ('Hello World')),
    constant_2_int AS (VALUES (100))
SELECT *
FROM some_table
WHERE table_column = (table constant_1_str)
LIMIT (table constant_2_int)

或者,您可以使用SELECT * FROM constant_name代替TABLE constant_name,这对于不同于Postgresql的其他查询语言可能无效。

答案 8 :(得分:2)

在DBeaver中,您可以像在代码中一样在查询中使用参数,因此可以使用:

SELECT *
FROM somewhere
WHERE something = :myvar

运行查询时,DBeaver将询问您:myvar的值并运行查询。

答案 9 :(得分:1)

是的,没有一种生动明确的方法来声明单值变量,您可以做的是

with myVar as (select "any value really")

然后,要访问此构造中存储的值,请执行

(select * from myVar)

例如

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

答案 10 :(得分:0)

您可以诉诸工具的特殊功能。就像DBeaver自己的专有语法一样:

@set name = 'me'
SELECT :name;
SELECT ${name};

DELETE FROM book b
WHERE b.author_id IN (SELECT a.id FROM author AS a WHERE a.name = :name);