SQL스크립트 파일에는 (일반적으로) 다음이 포함될 수 있습니다.SQL- 클라이언트 측에서 구문 분석되는 변수 대체를 포함한 특정 지시문. 다음을 통해 PostgreSQL 서버로 전송될 일련의 SQL 명령을 얻는 일반적인 방법을 찾고 있습니다.SQL, 모든 클라이언트 처리가 완료된 후. 또한 이는 오프라인으로 작동해야 합니다. 따라서 실시간으로 실행되거나 롤백 트랜잭션을 사용하는 소켓 스니핑과 관련된 솔루션은 제외됩니다. 누구든지 이것을 달성하는 방법을 알고 있습니까?
편집하다:왜냐하면SQL조건부 메타 명령( \if
, ...)은 이전 SQL 문의 평가에 의존할 수 있으며 모든 경우에 완전한 구문 분석을 하는 것이 불가능하다는 것을 알고 있습니다.SQL시험 실행 옵션을 사용할 수 없습니다). 이 문제에 대한 유효한 해결책은 여전히 단순히 무시하는 것입니다.SQL그러나 조건이 있습니다.
답변1
이 Bash 스크립트 확장SQL~의\포함하다(\나) 그리고\include_relative(\ir) 메타 명령을 실행하고 단일 구문 분석된 스트림을 출력합니다.표준 출력. 게시했을 때 개선할 수 있는 몇 가지 사항을 발견했지만(주로 두 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
이 스크립트는 구문을 지원하지 않으므로 문자열이나 큰따옴표로 묶인 리터럴 식별자 내에 나타날 수 있는 포함과 유사한 하위 문자열은 대체됩니다.