Как объявить переменную в запросе PostgreSQL

как объявить переменную для использования в запросе PostgreSQL 8.3?

в MS SQL Server я могу сделать следующее:

DECLARE @myvar INT
SET @myvar = 5

SELECT *
FROM somewhere
WHERE something = @myvar

Как сделать то же самое в PostgreSQL? Согласно документации переменные объявляются просто как " тип имени;", но это дает мне синтаксическую ошибку:

myvar INTEGER;

может кто-нибудь дать мне пример правильного синтаксиса?

8 ответов


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

Я достиг той же цели с помощью WITH п., это далеко не так элегантно, но могут делать то же самое. Хотя для этого примера это действительно перебор. Я также не особо рекомендую это.

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

вы также можете попробовать это в PLPGSQL:

DO $$
DECLARE myvar integer;
BEGIN
    SELECT 5 INTO myvar;

    DROP TABLE IF EXISTS tmp_table;
    CREATE TABLE tmp_table AS
    SELECT * FROM yourtable WHERE   id = myvar;
END $$;

SELECT * FROM tmp_table;

выше требуется Postgres 9.0 или более поздней версии.


Это зависит от вашего клиента.

однако, если вы используете psql в клиент, то вы можете использовать следующее:

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

Настройки Динамической Конфигурации

вы можете "злоупотреблять" динамическими настройками конфигурации для этого:

-- 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


использование временной таблицы вне 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;

Я хочу предложить улучшение для @DarioBarrionuevo это, чтобы упростить использование временных таблиц.

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;

пример использования подготовка отчетности. Вы все еще не можете использовать ?, но вы можете использовать $n Примечание:

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