PostgreSQL 8 min read

psqlでSQLファイルを実行する ― -fと\i、エラーで止めるON_ERROR_STOPと終了コード

※この記事にはアフィリエイト広告(プロモーション)が含まれます。

この記事の出力は PostgreSQL 18.6(Ubuntu 26.04)の psql で採りました。

まず見る(結論)

psql -d mydb -f setup.sql                          # 実行(エラーがあっても最後まで流れる)
psql -d mydb -v ON_ERROR_STOP=1 -f setup.sql       # 最初のエラーで止める(終了コード 3)
psql -d mydb -1 -v ON_ERROR_STOP=1 -f setup.sql    # 全体を1トランザクションに(失敗したら全部戻る)
psql -d mydb -c 'SELECT 1'                         # 1文だけ
mydb=# \i /path/to/setup.sql                       # psql の中から

バッチやデプロイで使うなら -v ON_ERROR_STOP=1 を付けます。

エラーが出たときの動き

3行目でキー重複になるファイルで比べました。

CREATE TABLE t2 (id int PRIMARY KEY);
INSERT INTO t2 VALUES (1);
INSERT INTO t2 VALUES (1);   -- 3行目: duplicate key value violates unique constraint
INSERT INTO t2 VALUES (2);
SELECT count(*) FROM t2;
オプション 3行目より後 表に残ったもの 終了コード
なし 実行される(count は 2) 1, 2 0
-v ON_ERROR_STOP=1 実行されない 1 3
-1 current transaction is aborted で全部失敗 表ごと無し 0
-1 -v ON_ERROR_STOP=1 実行されない 表ごと無し 3

エラーは psql:/tmp/fsv/err.sql:3: ERROR: ... の形で、ファイル名と行番号を付けて標準エラーに出ます。失敗したら全部戻し、終了コードでも判定したいなら -1 と -v ON_ERROR_STOP=1 を両方付けます。

psql の終了コード

コード 実際に出た場面
0 正常終了。ON_ERROR_STOP 無しなら SQL エラーがあっても 0
1 -f のファイルが無い(No such file or directory)、-c の文が失敗
2 接続できない(パスワード誤り・サーバー停止・DB が無い)
3 ON_ERROR_STOP でスクリプトが止まった

-c で文を渡す

-c 'SELECT 1 AS a; SELECT 2 AS b' と1つにまとめても、-c 'SELECT 1 AS a' -c 'SELECT 2 AS b' と分けても、両方の結果が表示されました。ただし1つの -c に複数の文を書くと、まとめて1トランザクションで実行されます。-c 'CREATE TABLE t3 (id int); INSERT INTO t3 VALUES (1); INSERT INTO t3 VALUES (1/0)' は division by zero で終了コード 1 になり、t3 は作られていませんでした。

\i と \ir の違い

\i の相対パスは psql を起動したディレクトリから、\ir は \ir を書いたファイルのあるディレクトリから探します。sub/main.sql から同じフォルダの child.sql を読む場合で比べました。

実行のしかた \i child.sql \ir child.sql
別のディレクトリから psql -f /tmp/fsv/sub/main.sql child.sql: No such file or directory 読める
cd /tmp/fsv/sub してから psql -f main.sql 読める 読める

ファイルから別のファイルを読み込むなら \ir を使います。\i で読み込みに失敗しても、終了コードは 0 でした。

変数を渡す

-- var.sql
SELECT :'name' AS name, :id AS id;
SELECT * FROM t1 WHERE id = :id;
psql -d mydb -v name=taro -v id=1 -f var.sql

:'name' は単一引用符で囲んだ文字列('taro')、:id はそのまま(1)に置き換わります。-v を付け忘れると syntax error at or near ":" になります。

結果をファイル・CSV に出す

オプション 出力
-At 1|a(見出し・罫線・件数なし)
-At -F ',' 1,a
--csv id,name と 1,a(見出し付き)
-o out.txt 結果をファイルへ。NOTICE やエラーは画面に出る
-L log.txt 実行した文と結果をファイルに追記
-e / -a 実行した文を結果の前に表示
-q CREATE TABLE INSERT 0 1 などの完了メッセージを出さない

シェルの変数に値を1つだけ取り込むなら -At を使います。CSV の入出力は COPY と \copy の記事に書きました。

ファイルの中身で引っかかる点

  • BOM 付き UTF-8・CRLF の改行は、どちらもそのまま実行できた
  • 文の終わりのセミコロンを忘れると、次の文とつながって syntax error at or near "2"(行番号は次の文の行)
  • ファイル最後の文はセミコロンが無くても実行される
  • 標準入力からも流せる(psql < setup.sql か -f -)。-f - ではメッセージに psql:<stdin>:1: と行番号が付き、リダイレクトだけでは付かない

接続オプション

-h ホスト、-p ポート、-U ユーザー、-d データベースです。パスワードは PGPASSWORD か ~/.pgpass で渡します。-X を付けると ~/.psqlrc を読まないので、スクリプトの結果が個人の設定に左右されません。接続できないときは password authentication failed の記事と 外部から接続できないときの記事を見てください。

関連: PostgreSQLでテーブル一覧を表示する / データベース一覧と\c / pg_dumpとpg_restore

PostgreSQL をもっと深く知るための本

PostgreSQL実践入門 ──アーキテクチャ、運用監視、性能改善

技術評論社・2026年2月

アーキテクチャから運用監視・性能改善までを扱う。付録に PostgreSQL 18 の新機能と設定項目の差分がある。

Amazonで見る

[改訂3版]内部構造から学ぶPostgreSQL ―設計・運用計画の鉄則

技術評論社・2022年11月・PostgreSQL 14 ベース

内部構造の理解から、設計と運用計画の立て方を学ぶ。

Amazonで見る

Amazonのアソシエイトとして、FIRE SE は適格販売により収入を得ています。