単純な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 $$;

また、最後の挿入 IDを取得できます。

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
DOの近くでエラーが発生しないため、plpgsql言語の開始と終了の間にいくつかの関数があります。
Ash

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

1
これはPostgreSQLを完全に初めて使用することでしばらくの間私を驚かせました。さらにいくつかのヒントがあります。+セミコロンでステートメントを終了してください。+変数識別子がないので、あいまいな列名を避けるために_または類似のものを使用することができます。+このようなDECLARE _accountid INT:= 1;を使用して、変数の値をインラインで設定できます。
コーダー、2017

1
私のために働かないでください。リスを使用します。エラー:エラー:「$$」またはその付近のドル記号で囲まれていない文字列
Oliver Watkins

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

3
私のために働かないでください。リスを使用します。エラー:エラー:「$$」またはその付近のドル記号で囲まれていない文字列
Oliver Watkins

変数を使用するためには、他の変数と同じように接頭辞a を付けてはならないことを理解するのにしばらく時間がかかりました:。@ achilles-ram-nakirekantiあなたはこれを使用して例をselectステートメントに追加してこれをより明確にすることができますか?
exhuma

28

以下を使用できます。

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

それでいい


3
エラー:「\」またはその近くの構文エラー何が欠けていますか?
scw

14
@scwこれはpsqlコンソールからのみ使用できます。これをアプリのSQLに書き込むことはできません。
オーエンスマーティン2016年

...あなたは、これはpsqlのににパイプされるもの。..やPSQLが読み込む任意のスクリプトで使用することができます@owensmartin
エヴァンキャロル

4
これはまったく質問に答えません。MS SQLでは、クエリでvarを定義して、同じツールですぐに使用できます。この質問のすべてのバージョンで、なぜ人々がこれを答えとして提案し続けるのかわかりません。

@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

たとえば、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;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.