Як ви використовуєте змінні в простому скрипті PostgreSQL?


99

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

DECLARE @List AS VARCHAR(8)

SELECT @List = 'foobar'

SELECT *
FROM   dbo.PubLists
WHERE  Name = @List

Як це робиться в PostgreSQL? Чи можна це зробити?


Відповіді:


131

Повна відповідь міститься в офіційній документації 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.
Еш

49
код у цьому прикладі не працює. 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
Ясен,

1
Будучи абсолютно новим у PostgreSQL, це на деякий час мене закинуло, ось ще кілька порад: + Не забудьте закінчити свої висловлювання крапкою з комою! + Оскільки не існує ідентифікатора змінної, ви можете використовувати _ або щось подібне, щоб уникнути неоднозначних назв стовпців. + Ви можете встановити для змінної значення у рядку, використовуючи, як це ОГОЛОШИТИ _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
не працюй на мене. За допомогою білки. Помилка: ПОМИЛКА: незавершений рядок із котируванням у доларах біля "$$" або біля нього
Олівер Уоткінс,

Мені знадобився деякий час, щоб зрозуміти, що для того, щоб використовувати змінну, ви не повинні додавати до неї префікс, :як з іншими змінними. @ achilles-ram-nakirekanti, ви можете додати приклад, використовуючи це, у selectзаяві, щоб зробити це зрозумілішим?
ексгума

28

Ви можете використовувати:

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

Це буде робити


3
ПОМИЛКА: синтаксична помилка біля або біля "\" Що мені не вистачає?
scw

14
@scw Це доступно лише на psqlконсолі. Ви не зможете записати це в SQL додатка.
owensmartin

@owensmartin Ви зможете використовувати це все, що передається до psql .. або будь-який скрипт, який читає psql ...
Еван Керролл,

4
Це взагалі не відповідає на питання. У MS SQL ви можете визначити var у запиті та використовувати його там же, у тому самому інструменті. Я не розумію, чому люди продовжують пропонувати це як відповідь у кожній версії цього питання.
камінь

@stone, мабуть, тому, що це величезна "помилка", postgresqlі це найменш гірша альтернатива. загалом я був дуже задоволений postgresql: але це напрочуд великий провал
Джавадба

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

Для використання змінних у, наприклад, alter table:

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.