SQLスクリプトファイルには(通常)次のものを含めることができます。SQL– クライアント側で解析される変数置換を含む特定のディレクティブ。次のようにして、PostgreSQLサーバーに送信される一連のSQLコマンドを取得する一般的な方法を探しています。SQL、すべてのクライアント処理が完了した後。また、これはオフラインで機能する必要があります。したがって、リアルタイムで実行されるか、またはロールバックトランザクションを使用するソケットスニッフィングに関連するソリューションは除外されます。誰でもこれを達成する方法を知っていますか?
編集する:なぜならSQL条件付きメタコマンド(\if
、...)は以前のSQL文の評価に依存する可能性があり、すべての場合に完全な解析を行うことは不可能であることがわかります。SQLテスト実行オプションは利用できません)。この問題に対する有効な解決策は、まだ単純に無視することです。SQLしかし、条件があります。
答え1
このBashスクリプト拡張SQL~の\含む(\私)と\include_relative(\ir)メタコマンドを実行し、単一の解析されたストリームを出力します。標準出力。公開したときに改善できるいくつかの点が見つかりましたが(主に2つのコマンドをマージread -r line
)、スクリプトはまだうまくいきます(テストした結果)。
#!/bin/bash
incl='*([[:space:]])\\@(include?(_relative)|i?(r))+([[:space:]])*'
# Recursively process single \include (\i) or \include_relative (\ir) meta-command
process() {
# If current line is an '\include' ('\i') or '\include_relative' ('\ir') meta-command, substitute with file contents
if [[ "$1" == $incl ]]; then
# Read included file's name
filename="$(echo "$1" | awk '{print $2}')"
# Read included file's contents and process each line recursively
while IFS= read -r line; do
process "$line"
done < "$filename"
# Else, echo the line
else
echo "$1"
fi
}
# Output usage information with '--help' or '-h' switch
if [[ ' --help -h ' =~ " $1 " ]]; then
echo "USAGE: pg_psqlexpand [workdir] [-h|--help]"
echo
echo "Expands in place `\include' (`\i') and `\include_relative' (`\ir') meta-commands in psql scripts."
echo
echo "Connect pipe or use redirection for I/O."
echo "Paths are resolved relative to `workdir' (defaults to current working directory)."
exit 0
else
# If working directory is specified, cd into it (defaults to '.')
cd "${1:-.}"
while read -r line; do
process "$line"
done
fi
これにより、複雑なマルチファイルスクリプトを単一のファイルにマージしてスキャンできます。また、これらのスクリプトをその場所から渡すこともできます。SQL次に実行ポストグレススーパーユーザーポストグレスアクセスできない(通常は発信者のホームディレクトリの場所):
## Merge into single file
$ pg_psqlexpand < entry_point.psql > merged.psql
## Pipe to psql running as postgres
$ pg_psqlexpand < entry_point.psql | sudo -iu postgres psql
私はほぼ一週間以上上記のスクリプトを使用しており、うまく動作しています。私が経験した唯一の欠点は、ファイル名と行番号に関するデバッグ情報がプロセスから失われることです。回避策として、次のメタコマンドSQL大きな困難なしにデバッグするのに十分な情報を提供するエントリポイント:
-- Error handling
\set VERBOSITY verbose
\set SHOW_CONTEXT errors
\set ON_ERROR_STOP on
このスクリプトは構文をサポートしていないため、文字列または二重引用符で囲まれたリテラル識別子内に現れる可能性がある埋め込みに似た部分文字列は置き換えられます。