0

私はpostgresが初めてで、データの読み込みをいじっています。postgres 9.2 仕様のテーブル定義は次のとおりです。

CREATE TABLE weather (
    city varchar(80),
    temp_lo int, -- low temperature
    temp_hi int, -- high temperature
    prcp real, -- precipitation
    date date
 );

次のデータ ファイル (weather.txt) を用意しました。

San Francisco   43  57  0.0 '1994-11-29'
Hayward 54  37  0.0 '1994-11-29'

COPY コマンドを実行しました。

COPY weather FROM '~aviad/postsgres/playground/weather.txt';

今、実行するselect * from weather;と、都市の値が一重引用符で囲まれていることがわかります。INSERTこれは、単純な例を実行すると発生しません。

INSERT INTO weather VALUES ('San Francisco', 46, 50, 0.25, '1994-11-27');

私は疑問に思う:

  1. テキスト値を一重引用符で囲む理由は何ですか?
  2. COPY一重引用符のラップを回避するために使用されるファイルにテキスト データを配置する正しい方法は何 ですか?
4

2 に答える 2

2

あなたが質問で説明していることは、明らかに実際に起こっていることではありません。COPY冗長な一重引用符を含む文字列リテラルを列にインポートしようとすると失敗しdateます。

冗長な引用符を取り除くには、列のある一時テーブルにインポートしてから、ターゲット テーブルで引用符をトリミングします。textINSERT INTO

CREATE TEMP TABLE wtmp (
   city text
 , temp_lo int
 , temp_hi int
 , prcp real
 , date text  -- note how I use text here.
);

COPY wtmp FROM '~aviad/postsgres/playground/weather.txt';

INSERT INTO weather (city, temp_lo, temp_hi, prcp, date)
SELECT city, temp_lo, temp_hi, prcp, trim(date, '''')::date
FROM   wtmp
-- ORDER BY ?
;

一時テーブルは、セッションの終了時に自動的に削除されます。

識別子としての予約語

マニュアルから例をコピーしたようです。現在のマニュアルへのディープ リンクは次のとおりです。

正しいのですが、マニュアルのその例は残念です。列名などの予約語dateは使用しないことをお勧めします。ご覧のとおり、すべての SQL 標準で予約語です datePostgres での使用が許可されており、単純な例がいかに魅力的かがわかります。しかし、それは良い考えではありません。一般に、予約語を識別子として使用しないようにする習慣が必要です。これにより、紛らわしいエラー メッセージが表示され、不必要に互換性のない SQL コードが生成されます。

于 2013-01-29T12:02:52.297 に答える
0

1 - 引用符で囲まれた識別子でテキストをラップする練習は、ファイル内で使用されている区切り記号 (この場合はカンマ) がテキスト文字列内にも現れる場合に行われます。

2 - postgres についてはよくわかりませんが、COPY コマンドで引用符で囲まれた識別子を指定すると、インポート中に削除する必要があります。

COPY weather FROM '~aviad/postsgres/playground/weather.txt' (QUOTE '?');

それらの線に沿った何か。? を置き換えてみてください。引用された識別子を使用-あなたの場合、最初にこれを試します:

COPY weather FROM '~aviad/postsgres/playground/weather.txt' (QUOTE '''');

COPY コマンドで使用できるさまざまなスイッチが多数あるため、http ://www.postgresql.org/docs/9.2/static/sql-copy.html も確認してください。

于 2013-01-29T09:31:01.367 に答える