- ベストアンサー
postgrsqlのCopyコマンドでの構文エラーの原因は何か?
- postgrsqlのCopyコマンドを使用してプレーンデータをバックアップしようとしていますが、リストアできないトラブルが発生しています。
- さらに、copyコマンドに関連して検証用の簡単なsqlコマンドを実行したところ、構文エラーが発生しました。
- このエラーの原因を解明するために、copyコマンドの使用方法やデータ形式を調査しています。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
> これの何がいけないのでしょうか? ---------------------------------------- 1【TAB】aaa 2【TAB】bbb 3【TAB】ccc \. ---------------------------------------- の部分がCOPYコマンド向けのデータそのものであり、psqlの入力として正しくない為、エラーとなっています。 リストアの際には下記の様なコマンドを実行するかと思います。 psql リストア先のDB < pg_dumpで出力したファイル これは、pg_dump で出力した内容をpsqlが標準入力から受け取って実行する事になりますが、 copy tb1 (item1, item2) FROM stdin; の行を受け取って実行すると標準入力からのデータをCOPYコマンドの入力として受取る状態になります。したがって、その後に続く行はCOPYコマンド自体の入力として扱われ、SQL文としては処理されません。\.に到達するとCOPYコマンドはデータが終了したと判断し、標準入力の受け取りを止め、それまでのデータをテーブルに挿入して終了します。 \.の次の行からは、再びpsqlが標準入力の内容を直接処理する事になります。 http://www.postgresql.jp/document/9.3/html/sql-copy.html
その他の回答 (1)
- mitoneko
- ベストアンサー率58% (469/798)
最近は、ユーティリティーもみんなGUIになってしまって・・・こういう感覚ってわかりにくいのかもしれませんね。 Postgreにも、コマンドラインのクライアントとして、psqlというユーティリティーがついています。 コマンドラインから、psql.exeを実行して、あなたの書いたSQLを一行ずつ、手打ちして(カット&ペーストはしないこと)試してみてください。 create table・・・を打つ時には、画面にpostgre#=というプロンプトが出てますよね。 create table文の2行目を打つ時には、プロンプトが少し変わっているはずです。継続行の認識をしているんです。 最後の;を打つと、テーブルを作った旨の表示が出ます。 続いて、次のcopy文を打ちますが・・・ copy文の行を打ち終わってリターンすると・・・ プロンプトがおかしくないですか? お構いなしでデータをうち、\.の行を打って、リターンを押すと、コマンドを実行した旨の表示が出て、またプロンプトが復活しましたね。 このプロンプトが無くなったのが、あなたの混乱の原因なんです。 プロンプトが無くなったと言うことは、この間は、キーボードの入力も表示も、qsql.exeとは別のものが支配していると言うことです。具体的には、copyコマンドが支配しています。 この間のキーボードからの入力は、qsqlへの入力では無く、copyコマンドへの入力として扱われていると言うことです。 「\.」を入力すると、copyコマンドは、入力の終わりを認識して、キーボードの入力を元のqsqlへ返します。 さて、psadminなんですが・・・ guiのSQLコマンドの実行ラインが、これと同じ動きをしてくれれば良いんですけど・・・残念ながら、stdinの解釈がCUIの時と違い、copyコマンドの次の行をcopyコマンドの支配下に置いていません。copyコマンドには、「stdinからの入力は無いよ」と言い放ち、次の行は、ちゃんとSQL文として送信しているのです。本来は、copyコマンドに渡すべき入力を渡さないのですから、挙動はおかしくなります。 対処は、いくつか・・・ ・sqlをファイルに保存してファイルから実行してみる。 ・copy文の from stdinの所のstdinを代わりにファイル名にしてみる。(もちろん、データの入ったテキストファイルです。) ・こういう、stdinがらみの実験は、psqlでする。
お礼
有難う御座います。 概念上のお話はともかく、 具体的に 「どうすれば出来る」 あるいは、 「そのやり方を突き詰めても出来ないので諦めた方が良い」 といった、答えが見つかりません。 幾つか試してみましたが、いまだ成功していません。 ・sqlをファイルに保存してファイルから実行してみる。 バックアップからPLAIN、データのみで実行して保存すると、sqlをファイルが出来ます。 それを実行出来ていません。 ・copy文の from stdinの所のstdinを代わりにファイル名にしてみる。(もちろん、データの入ったテキストファイルです。) COPY tb1 (item1, item2) FROM E'c:\\temp\\test.csv'; のようにファイルを指定しても成功していません。
お礼
有難う御座います。 COPY コマンドも CREATE TABLE も SELECT も同列のコマンドのように紹介されているので、pdAdminIIIのSqlコマンドにコピペすれば実行可能だと思いました。 inssert into tb1 (item1, item2) values (1,'aaa'); inssert into tb1 (item1, item2) values (2,'bbb'); inssert into tb1 (item1, item2) values (3,'ccc'); を実行するのと同じような感覚で copy tb1 (item1, item2) FROM stdin; 1【TAB】aaa 2【TAB】bbb 3【TAB】ccc \. を実行していました。 そういうモノではないという事でしょうか?