PostgreSQL 8.3クエリで使用する変数をどのように宣言しますか?
MS SQL Serverではこれが可能です。
DECLARE @myvar INT
SET @myvar = 5
SELECT *
FROM somewhere
WHERE something = @myvar
PostgreSQLで同じことをするにはどうすればいいですか?ドキュメントによれば、変数は単に "name type;"として宣言されていますが、これは私に構文エラーを与えます。
myvar INTEGER;
誰かが私に正しい構文の例を教えてもらえますか?
PostgreSQLにはそのような機能はありません。それはpl/PgSQL(または他のpl/*)でのみ可能ですが、プレーンSQLではできません。
例外は、変数として、または変数のTuple
としても機能することができるWITH ()
クエリです。それはあなたが一時的な値のテーブルを返すことを可能にします。
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
あなたがテキスト変数を使っているならば、あなたは引用する必要があります。
\set myvar 'sometextvalue'
select * from sometable where name = :'myvar';
あなたはこれのために動的設定を "悪用"することができます。
-- 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値であるため、それらを使用するときは正しいデータ型にキャストする必要があります。 \set
はpsql
でのみ機能しますが、これはどのSQLクライアントでも機能します。
上記にはPostgres 9.2以降が必要です。
以前のバージョンでは、変数は使用される前にpostgresql.conf
で宣言されなければなりませんでした、それでそれはその有用性を幾分制限しました。実際には完全に変数ではなく、基本的に接頭辞であるconfig "class"です。しかし、一度接頭辞が定義されると、postgresql.conf
を変更せずに任意の変数を使用できます。
提案されているように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'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;
これは PREPARE文 を使った例です。まだ?
を使用することはできませんが、$n
表記を使用することはできます。
PREPARE foo(integer) AS
SELECT *
FROM somewhere
WHERE something = $1;
EXECUTE foo(5);
DEALLOCATE foo;
この解決策は、 fei0x によって提案されたものに基づいていますが、クエリ内の定数の値リストを結合する必要がなく、クエリの開始時に定数を簡単にリストできるという利点があります。再帰的なクエリでも機能します。
基本的に、すべての定数はWITH値の中の単一値のテーブルdeclaratedであり、クエリの残りの部分のどこでも呼び出すことができます。
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とは異なる他のクエリ言語には無効な場合があります。
確かに、単一値の変数を宣言するための鮮明で明確な方法はありません。できることは
with myVar as (select "any value really")
次に、この構造に格納されている値にアクセスするには、
(select * from myVar)
例えば
with var as (select 123)
... where id = (select * from var)