psql
大きなオブジェクトとして保存する場合を除いて、ファイルを直接読み込むことはできません。その場合は、を使用できますlo_import
。psql
コマンドを参照してください\lo_import
。
更新:@AlexandreAlvesは、使用中にファイルコンテンツを実際に丸呑みできることを指摘しています
\set myvar = `cat somefile`
次に、それを。でpsql
変数として参照します:'myvar'
。ハンディ。
シェルを使用してファイルを読み取ってフィードすることはpsql
可能ですが、シェルはパラメーター化されたクエリをサポートするネイティブPostgreSQLデータベースドライバーもテキストエスケープ機能も提供しないため、せいぜい厄介です。あなたは逃げるあなた自身のひもを転がさなければならないでしょう。
それでも、入力ファイルのテキストエンコーディングが有効であることを知っておく必要があります。client_encoding
そうしないと、ガベージを挿入したり、エラーが発生したりします。Python、Perl、Ruby、JavaなどのPostgreSQLと適切に統合することで、言語で簡単に実行できるようになります。
ただし、本当に必要な場合は、bashでやりたいことを実行する方法があります。SQLインジェクション攻撃を防ぐために、ランダム化された区切り文字でPgの区切られたドル引用符を使用します。完璧ではありませんが、かなり近いです。私は今例を書いています。
問題のあるファイルを指定します。
$ cat > difficult.txt <__END__
Shell metacharacters like: $!(){}*?"'
SQL-significant characters like "'()
__END__
およびサンプルテーブル:
psql -c 'CREATE TABLE testfile(filecontent text not null);'
あなたはできる:
#!/bin/bash
filetoread=$1
sep=$(printf '%04x%04x\n' $RANDOM $RANDOM)
psql <<__END__
INSERT INTO testfile(filecontent) VALUES (
\$x${sep}\$$(cat ${filetoread})\$x${sep}\$
);
__END__
これは少し読みにくいかもしれませんし、ランダムな文字列の生成はbash固有ですが、おそらく移植可能なアプローチがあると確信しています。
英数字(便宜上16進数を使用)で構成されるランダムなタグ文字列が生成され、に格納されseq
ます。
psql
次に、引用符で囲まれていないヒアドキュメントタグを使用して呼び出されます。文字列内のシェルメタ文字を解釈しないよう<<'__END__'
に指示するように、引用符がないことは重要ですが、プレーンではシェルがそれらを解釈できます。ヒアドキュメントに置き換える必要があるため、メタ文字を解釈するためのシェルが必要です。また、ファイルテキストを挿入するために(バッククォートと同等)を使用する必要があります。ヒアドキュメントタグは有効なPostgreSQL識別子である必要があるため、の各置換の前にあります。そのため、タグは数字ではなく文字で始まる必要があります。PostgreSQLのドル引用符はの形式であるため、各タグの最初と最後にエスケープされたドル記号があります。bash
<<__END__
sep
$(...)
x
seq
$taghere$quoted text$taghere$
bash testscript.sh difficult.txt
したがって、ヒアドキュメントが次のようなものに展開されるときにスクリプトが呼び出されると、
INSERT INTO testfile(filecontent) VALUES (
$x0a305c82$Shell metacharacters like: $!(){}*?"'
SQL-significant characters like "'()$x0a305c82$
);
タグは毎回変化するため、引用を途中で終了することに依存するSQLインジェクションのエクスプロイトは困難です。
それでも実際のスクリプト言語を使用することをお勧めしますが、これはそれが実際に可能であることを示しています。