\i <file_path>
を実行するだけです。
postgres=# \i sqls/create-table.sql
少しまとまった SQL を流したい場合は、 中からシェルコマンドを実行すると組み合わせて、
\! vim sqls/hoge.sql
に SQL を書く\i sqls/hoge.sql
で実行する
とすると楽かもしれません。
\i <file_path>
を実行するだけです。
postgres=# \i sqls/create-table.sql
少しまとまった SQL を流したい場合は、 中からシェルコマンドを実行すると組み合わせて、
\! vim sqls/hoge.sql
に SQL を書く
\i sqls/hoge.sql
で実行する
とすると楽かもしれません。
-v, --set, --variable
オプションを使います。その後key=value
の形で設定していきます。
設定した値は.sql
ファイルの中で:key
と:
を頭に付けて参照できます。
foo
は変数で渡す形で書くとこのような SQL になります。
create table :schema.hoge ();
-- CREATE TABLE
この内容が書かれている.sql
ファイルは、schema
という変数を定義した上で実行されることを期待しています。そのように変数を実行し、かつ SQL を流すコマンドは以下です。
psql -v schema=foo < create-hoge.sql
# CREATE TABLE
ちゃんとできていればいい感じです。
psql -c '\dt foo.*'
# List of relations
# Schema | Name | Type | Owner
# --------+------+-------+----------
# foo | hoge | table | postgres
# (1 row)
-c, --command
オプションを使います。あとに SQL やpsql
内部で使えるコマンドを書きます。
psql -c 'select 1 as one'
# one
# -----
# 1
# (1 row)
psql
内部では\x
コマンドでカラムの縦・横並びを切り替えできました。これはコマンドラインでは-x, --expanded
オプションで切り替えられます。
psql -x -c 'select 1 as one'
# -[ RECORD 1 ]
# one | 1
ダンプにはそれ用のコマンドpg_dump
がありこれでダンプファイルの作成ができます。これの接続時のオプションなどはpsql
と同じです。
以下でoutput.sql
にダンプできます。
PGPASSWORD=password pg_dump \
-h host \
-p port \
-U username \
foo_database > output.sql
接続情報にはpostgres://
スキーマを使うこともできます。
pg_dump postgres://.../foo_database > output.sql
ダンプされたファイルはそのままpsql
で扱える形なので、シェルのリダイレクションで取り込むことができます。database
がない場合は先に作っておきます。
psql postgres://... -c 'create database foo_database'
psql postgres://.../foo_database < output.sql
\watch
コマンドを使います。SQL文; \watch 2
のように実行すると SQL 文を2秒毎に実行してくれます。
ターミナルを2つ開いて以下のようにして見てみます。テーブルはfoo
という名前のものを使います。
テーブルに3秒毎にinsert
する
テーブルの最新1件を2秒毎に表示する
とりあえず以下でfoo
を作ります。
create table foo (
id serial primary key not null
);
1番目の方では以下でinsert
を走らせます。\watch 3
で3秒毎走らせるということになります。
ちなみにdefault values
はすべてのカラムでデフォルト値を使うということになるのでvalues
を省略できます、
insert into foo default values; \watch 3
2番目の方では以下でselect
を走らせます。
select * from foo order by id desc limit 1; \watch 2
これで3秒毎に新しいid
のデータが増えていくので、その度select
で取得するデータも変わるはずです。
右が1です。左側には1,2回毎に新しいレコードが表示されています。(\x
で縦表示にしています)
色々と結果を見ながらいじりたい時に便利だと思います。
\set name value
を使います。例えば以下でtablename
にposts
という値を設定しています。
postgres=# \set tablename posts
設定できたかどうかは\set
と実行します。恐らく最後に出てくるはずです。
postgres=# \set
...
tablename = 'posts'
何か-
を挟んだもの(table-name
みたいな)変数名はうまく SQL の中で使えなかったので、避けたほうがいいかもしれないです。
では、使ってみます。
postgres=# create table :tablename (content text);
CREATE TABLE
postgres=# insert into :tablename values ('aaa');
INSERT 0 1
postgres=# select * from :tablename;
content
---------
aaa
(1 row)
「もう必要ないな」となったら\unset name
で削除できます。
postgres-# \unset tablename
postgres=# \set
...
DO $$ ... $$
で SQL の塊を作ることができます。RAISE
はトランザクション時に予期せぬ事が起こったときに使うものみたいですが、これを使ってログみたいな情報を流せるみたいですね。
DO $$
BEGIN
RAISE NOTICE 'aaa % %', 'b', 'c';
END
$$;
NOTICE: aaa b c
DO
-h
オプションと同様に接続先のホストを指定できます。
psql -h ...
PGHOST=... psql
-p
オプションと同様に接続先のホストを指定できます。
psql -p ...
PGPORT=... psql
-U
オプションと同様に接続先のホストを指定できます。
psql -U ...
PGUSER=... psql
psql
コマンドを実行した時にパスワードを聞かれずにログインすることができます。
PGPASSWORD=... psql
以下のような Docker で Postgresql を起動するとして、
docker run --rm -p 54321:5432 postgres
.config/fish/config.fish
に以下のように書くとpsql
だけで接続できるようになります。
set -gx PGHOST 0.0.0.0
set -gx PGUSER postgres
set -gx PGPORT 54321
set -gx PGPASSWORD ''
\timing
コマンドを先に実行します。
\timing
-- Timing is on.
あとは好きなクエリを実行するとTime: 1 ms
のようにかかった時間も表示しれくれるようになります。
alter table hoge add id serial;
-- ALTER TABLE
-- Time: 9.109 ms
(親)SQL の中に( )
で囲んで子 SQL 文を書くと、実行時にその部分の結果に置き換わった状態で親 SQL が実行されます。
例えば以下のサブクエリは、bar
テーブルからvalue
がnju33
なレコードfoo_id
を返します。
select * from foo
where foo_id = (
select foo_id from bar where value = 'nju33'
);
例えばそれが33
だった場合、以下のように展開されます。
select * from foo where foo_id = 33;
またwith
構文を使う方法もあります。
環境。
create schema tmp;
set search_path to tmp;
create table foo (
id serial,
foo varchar(255)
);
create table bar (
id serial,
bar varchar(255)
);
insert into foo (foo) values ('a'), ('b'), ('c');
insert into bar (bar) values ('1'), ('2'), ('3');
以下はselect * from bar where id > 1
の結果テーブルに対してinner join
するという意味になる。
with as_bar as (select * from bar where id > 1)
select foo.id, foo.foo, as_bar.bar
from foo
inner join as_bar
on foo.id = as_bar.id;
この結果は以下のようになります。
id | foo | bar
----+-----+-----
2 | b | 2
3 | c | 3
(2 rows