質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.31%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

1回答

5879閲覧

psqlコマンドで、複数の外部ファイルに定義されたSQLを読み込んで実行していき、エラーはテキストに出力したい

NulluoKikiura

総合スコア34

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

2クリップ

投稿2021/10/26 14:44

やりたいこと

postgreSQLのDBに対し、psqlコマンドで複数の外部ファイルに定義されたSQLを読み込んで実行していき、エラーになったファイルがあった時に実行を停止させ、エラーの内容はテキストファイルで出力させたい

(環境:Windows10)

試したこと

下記のようにコマンドプロンプトからpsqlでDBに接続し、トランザクションを発行します
イメージ説明

↓ \i で insert_N.sqlを読み込み下記のように連続で実行していきます。
(insert_N.sqlにはINSERT文が多数書かれている想定)

psql

1\i insert_1.sql 2\i insert_2.sql 3\i insert_3.sql 4  : 5  :

↓そうすると画面にinsert_N.sqlの実行結果が出力されます

INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 :

ここで、エラーが起きた時に、今はコマンドプロンプトの画面をスクロールして
どのinsert_N.sqlでエラーが起きていたのか探してエラーに対処する……
という事をしていますがスクロールで探すのは手間なのでもっと効率化したいというのが実現したいことです

下記のように-bオプション(失敗したSQLコマンドを標準エラー出力に出力します)を使ったり、1>2>を用いて標準エラー出力のリダイレクトでテキストをはこうとしましたが、これを実行してDBのパスワードを入力すると応答が返ってこなくなってしまいます

$ psql -h localhost -p 5432 -U postgres -d dvdrental -b 1> info.txt 2> error.txt

下記の1.と2.を必須条件として実現したいです。3.は「できれば達成したい」レベルなので3はできなくても構いません。

  1. エラー出力をリダイレクトしてテキストに吐くようにする
  2. トランザクションを発行して、エラーが発生したときにはInsert_1.sql~Insert_N.sqlを実行する前の状態にロールバックしたい
  3. insert_N.sqlを全ファイル実行するのではなく、エラーになったファイルがあったら以後のファイルは処理しないようにしたい(できればしたい事)

お手数ですが、psqlコマンド、postgreSQLに詳しい方の知見をお待ちしております。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

insert.sqlというようなファイルを用意して、その中に\i insert_X.sqlを書き込みます。

\i insert_1.sql \i insert_2.sql \i insert_3.sql -- 以下略

そして、
$ psql -f insert.sql -1 -h localhost -p 5432 -U postgres -d dvdrental 2> error.txt
と実行してはどうでしょうか。
-fオプションは、指定したファイル内に記載されたSQL文およびバックスラッシュコマンドを実行する、というオプションです。
-1オプションは-fで実行される内容を、1トランザクションとして実行する、というオプションです。

これによって、

  1. エラー出力をリダイレクトしてテキストに吐くようにする

2> error.txtで実現可能。

  1. トランザクションを発行して、エラーが発生したときにはInsert_1.sql~Insert_N.sqlを実行する前の状態にロールバックしたい

-fオプションと-1オプションで実現可能。
1トランザクションで-fで指定されたファイルの内容が実行されるので、insert_X.sqlのいずれかでエラーが発生すると、自動的にロールバックされます。
つまり、エラーが発生する前に実行された内容も、エラーが発生した後に実行された内容も、データベースには一切反映されません。

あとは、2> error.txtに記載された先頭行のエラーメセージにさえ着目すればよいです。エラーメッセージには、どのファイルの何行目でエラーが発生したのかも記載されているので、エラーが発生したSQL文の特定も簡単です。

  1. insert_N.sqlを全ファイル実行するのではなく、エラーになったファイルがあったら以後のファイルは処理しないようにしたい(できればしたい事)

上記の方法だと、エラーが発生した後の処理も全て実行されてしまいます。
ただ、ERROR: current transaction is aborted, commands ignored until end of transaction blockというメッセージが出力されるだけで、全ての処理は無視されます。

投稿2021/11/13 19:25

synydy

総合スコア21

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NulluoKikiura

2021/11/27 06:56

返信おそくなって申し訳ありません。 おかげで、やりたいことが一通り実現できました。ありがとうございます
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問