Как использовать переменные в простом скрипте PostgreSQL?


99

Например, в MS-SQL вы можете открыть окно запроса и выполнить следующее:

DECLARE @List AS VARCHAR(8)

SELECT @List = 'foobar'

SELECT *
FROM   dbo.PubLists
WHERE  Name = @List

Как это делается в PostgreSQL? Это можно сделать?


Ответы:


132

Полный ответ находится в официальной документации PostgreSQL .

Вы можете использовать новую функцию анонимного блока кода PG9.0 ( http://www.postgresql.org/docs/9.1/static/sql-do.html )

DO $$
DECLARE v_List TEXT;
BEGIN
  v_List := 'foobar' ;
  SELECT *
  FROM   dbo.PubLists
  WHERE  Name = v_List;
  -- ...
END $$;

Также вы можете получить идентификатор последней вставки :

DO $$
DECLARE lastid bigint;
BEGIN
  INSERT INTO test (name) VALUES ('Test Name') 
  RETURNING id INTO lastid;

  SELECT * FROM test WHERE id = lastid;
END $$;

7
(И не забывайте, что ;после END $$, например:. END $$;)
KajMagnus

3
НЕ РАБОТАЕТ ДЛЯ МЕНЯ ОШИБКА РЯДОМ ДЕЙСТВИТЕЛЬНО, у меня также есть некоторые функции между началом и концом с языком plpgsql.
Эш

51
код в этом примере не работает. ERROR: query has no destination for result data HINT: If you want to discard the results of a SELECT, use PERFORM instead. CONTEXT: PL/pgSQL function inline_code_block line 7 at SQL statement
Jasen

1
Я был совершенно новичком в PostgreSQL, поэтому вот еще несколько советов: + Убедитесь, что вы заканчиваете свои операторы точкой с запятой! + Поскольку идентификатора переменной нет, вы можете использовать _ или что-то подобное, чтобы избежать неоднозначных имен столбцов. + Вы можете установить для переменной значение в строке, используя как это DECLARE _accountid INT: = 1;
The Coder

1
не работай на меня. Используя белку. Ошибка: ОШИБКА: незавершенная строка в кавычках в долларах на "$$" или рядом с ним
Оливер Уоткинс,

39
DO $$
DECLARE  
   a integer := 10;  
   b integer := 20;  
   c integer;  
BEGIN  
   c := a + b;
    RAISE NOTICE'Value of c: %', c;
END $$;

3
не работай на меня. Используя белку. Ошибка: ОШИБКА: незавершенная строка в кавычках в долларах на "$$" или рядом с ним
Оливер Уоткинс,

1
Мне потребовалось время, чтобы понять, что для того, чтобы использовать переменную, вы не должны ставить перед ней префикс, :как с другими переменными. @ achilles-ram-nakirekanti вы могли бы добавить пример, используя это в selectзаявлении, чтобы сделать это более понятным?
exhuma

28

Ты можешь использовать:

\set list '''foobar'''
SELECT * FROM dbo.PubLists WHERE name = :list;

Что будет делать


3
ОШИБКА: синтаксическая ошибка рядом с "\" Что мне не хватает?
scw

14
@scw Доступно только с psqlконсоли. Вы не сможете записать это в SQL вашего приложения.
owensmartin 07

@owensmartin. Вы сможете использовать все, что передается в psql ... или любой сценарий, который читает psql ...
Эван Кэрролл,

4
Это вообще не отвечает на вопрос. В MS SQL вы можете определить переменную в запросе и использовать ее прямо здесь, в том же инструменте. Я не понимаю, почему люди продолжают предлагать это в качестве ответа в каждой версии этого вопроса.
камень

@stone, по-видимому, потому, что это огромный промах postgresqlи наименее худшая альтернатива. в целом я очень доволен postgresql: но это на удивление большой провал
javadba

10

Вот пример использования переменной в plpgsql:

create table test (id int);
insert into test values (1);
insert into test values (2);
insert into test values (3);

create function test_fn() returns int as $$
    declare val int := 2;
    begin
        return (SELECT id FROM test WHERE id = val);
    end;
$$ LANGUAGE plpgsql;

SELECT * FROM test_fn();
 test_fn 
---------
       2

Посмотрите на plpgsql документов для получения дополнительной информации.


4

Я столкнулся с некоторыми другими документами, которые они используют \setдля объявления переменной сценария, но значение похоже на постоянное значение, и я нахожу способ, который может действовать как переменная, а не постоянная переменная.

Пример:

\set Comm 150

select sal, sal+:Comm from emp

Вот salзначение, которое присутствует в таблице emp и commявляется постоянным значением.


2

Я должен был сделать что-то вроде этого

CREATE OR REPLACE FUNCTION MYFUNC()
RETURNS VOID AS $$
DO
$do$
BEGIN
DECLARE
 myvar int;
 ...
END
$do$
$$ LANGUAGE SQL;

2

Postgresql не имеет простых переменных, вы можете использовать временную таблицу. переменные доступны только в блоках кода или как функция пользовательского интерфейса.

Если вам нужна простая переменная, вы можете использовать временную таблицу:

CREATE TEMP TABLE list AS VALUES ('foobar');

SELECT dbo.PubLists.*
FROM   dbo.PubLists,list
WHERE  Name = list.column1;

Дополнительным преимуществом является то, что этот подход не зависит от базы данных, что делает ваши тесты более переносимыми в серверной части.
епископ

2

Основываясь на ответе @ nad2000 и ответе @ Pavel здесь , здесь я закончил свои сценарии миграции Flyway. Обработка сценариев, в которых схема базы данных была изменена вручную.

DO $$
BEGIN
    IF NOT EXISTS(
        SELECT TRUE FROM pg_attribute 
        WHERE attrelid = (
            SELECT c.oid
            FROM pg_class c
            JOIN pg_namespace n ON n.oid = c.relnamespace
            WHERE 
                n.nspname = CURRENT_SCHEMA() 
                AND c.relname = 'device_ip_lookups'
            )
        AND attname = 'active_date'
        AND NOT attisdropped
        AND attnum > 0
        )
    THEN
        RAISE NOTICE 'ADDING COLUMN';        
        ALTER TABLE device_ip_lookups
            ADD COLUMN active_date TIMESTAMP;
    ELSE
        RAISE NOTICE 'SKIPPING, COLUMN ALREADY EXISTS';
    END IF;
END $$;


1

Для использования переменных, например, в таблице изменений:

DO $$ 
DECLARE name_pk VARCHAR(200);
BEGIN
select constraint_name
from information_schema.table_constraints
where table_schema = 'schema_name'
      and table_name = 'table_name'
      and constraint_type = 'PRIMARY KEY' INTO name_pk;
IF (name_pk := '') THEN
EXECUTE 'ALTER TABLE schema_name.table_name DROP CONSTRAINT ' || name_pk;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.