初めに
Qiita Engineer Festa 2024に参加中。完走目指してます。
他のメタコマンドについては以下から読んでください。
\gexecとは
現在の問い合わせバッファをサーバに送信し、問い合わせの出力(あれば)の各行の各列をSQL文として実行します。 例えば、
my_table
の各列にインデックスを作成するには次のようにします。=>SELECT format('create index on my_table(%I)', attname) ->FROM pg_attribute ->WHERE attrelid = 'my_table'::regclass AND attnum > 0 ->ORDER BY attnum ->\gexec CREATE INDEX CREATE INDEX CREATE INDEX CREATE INDEX
生成された問い合わせは行が返された順番で実行され、また2つ以上の列が返された場合は、各行の中で左から右に実行されます。 NULLのフィールドは無視されます。 生成された問い合わせは、そのままサーバに送信されて処理されるため、psqlのメタコマンドとすることはできず、またpsqlの変数の参照を含むこともできません。 個別の問い合わせで失敗した場合、残りの問い合わせの実行は
ON_ERROR_STOP
が設定されているのでなければ継続します。 個々の問い合わせの実行はECHO
の処理に従います。 (\gexec
を使う場合、ECHO
をall
あるいはqueries
に設定することが推奨されることが多いでしょう。) 問い合わせのログ出力、シングルステップモード、時間表示(timing)、およびその他の問い合わせ実行に関する機能は、生成された各問い合わせにも適用されます。現在の問い合わせバッファが空の場合、最も最近に送信された問い合わせが再実行されます。
試してみた
テーブルを用意する
CREATE TABLE source_table (
id SERIAL PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE target_table (
id INTEGER,
name VARCHAR(50)
);
INSERT INTO source_table (name) VALUES ('Alice'), ('Bob'), ('Charlie');
source_tableのデータを使ってtarget_tableにデータを挿入
postgres=# SELECT 'INSERT INTO target_table (id, name) VALUES (' || id || ', ''' || name || ''');'
FROM source_table
\gexec
INSERT 0 1
INSERT 0 1
INSERT 0 1
結果のSQLを実行してくれた。
ちなみに実行されたSQLは以下の通り
postgres=# SELECT 'INSERT INTO target_table (id, name) VALUES (' || id || ', ''' || name || ''');'
FROM source_table;
?column?
------------------------------------------------------------
INSERT INTO target_table (id, name) VALUES (1, 'Alice');
INSERT INTO target_table (id, name) VALUES (2, 'Bob');
INSERT INTO target_table (id, name) VALUES (3, 'Charlie');
(3 rows)
まとめ
これは実務でも活用できそうですね。
実際にクエリから新たなクエリを作って実行すると言うことはしていたので今度使ってみます。