質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

13274閲覧

WindowsバッチからPostgreSQLを使いCSVインポートについて

saki_study111

総合スコア13

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2020/01/31 00:01

編集2020/01/31 00:35

■質問内容
windowsバッチからPostgreSQLを呼び出してCSVをインポートしようとしています。
そこで問題となる点が数点ありますのでご存じの方がおられれば教えてもらいたいです。

1.バッチファイルからpsqlを実行した際にSQL側でエラーが発生してもバッチ側でエラーレベルが正しく取得できない。
SQLを外部ファイルにしているから問題なのかもしれません。
「-f "%SQLFILE%"」を「-c "select * from ..."」では正しくエラーレベルが取得できます。

2.CSVファイルがダブルコーテーション区切りの場合でCOPYコマンドでテーブルに入れる場合に「""」がnullにならない。
「with NULL ''」を書いても効かない。
そのためテンポラリテーブルに入れてから置換して別テーブルに入れています。

環境はwindows、PostgreSQL11を使用しています。

【bat】
@echo off
setlocal enabledelayedexpansion

set CSVFILE=C:\work\import_csv\import_test.csv
set SQLFILE=C:\work\import_sql\import_test.sql

(psql -h localhost -p 5432 -U postgres -d mydb -f "%SQLFILE%" -v CSV_PATH="%CSVFILE%")

echo %errorlevel%

endlocal
pause

【SQL】
-- テンポラリテーブル作成
create temp table temp_table1 (col1 text ,col2 text ,col3 text, col4 timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL);

-- CSVをテンポラリテーブルにimport
COPY
temp_table1
(col1, col2, col3)
FROM :'CSV_PATH' with encoding 'SJIS' csv HEADER
;

-- テンポラリテーブルからselectInsert(空文字をnullに変換)
insert into table1
select nullif(col1, ''), nullif(col2, ''), nullif(col3, ''), col4
from temp_table1;

【CSV】
"カラム1","カラム2","カラム3"
"0001","あ","え"
"0002","",""
"0003","い",""

【table1】
CREATE TABLE table1 (
col1 text,
col2 text,
col3 text,
col4 timestamp without time zone DEFAULT CURRENT_TIMESTAMP NOT NULL
);

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saki_study111

2020/01/31 02:06

スマホからの修正がうまくできないため、後に修正します。 コマンドプロンプト側でエラーレベルが取れない件については自己解決しました。 コマンドプロンプト側で PostgreSQLを呼び出す際に 「--set ON_ERROR_STOP=ON」を記載。 SQLファイル側で begin transaction; クエリー end transaction; を記載することにより、ロールバックも可能。
guest

回答2

0

postgres(V12 win)でのテストですが

psqlのエラー発生時に抜けるでコードが取れると思います。最後まで実行したい場合は別ですが。

psql

1\set ON_ERROR_STOP

””ではNULLになりませんが,,の無指定でnullになるでは駄目でしょうか?

csv

1"カラム1","カラム2","カラム3" 2"0001","あ","え" 3"0002",,"" 4"0003","い",

投稿2020/01/31 03:00

amura

総合スコア333

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saki_study111

2020/01/31 04:06

set ON_ERROR_STOPで大丈夫でした! NULLにするにはFORCE_NULL(カラム名)でいけるみたいです。
guest

0

ベストアンサー

一点目のpsqlのエラーコードについてですが、
psqlは途中のSQLでエラーが発生しても、致命的なエラーでない場合は最後まで実行します。
その結果、エラーコードとしては正常(0)が返ります。
途中のエラーで処理をとめて、エラーを検知したい場合はON_ERROR_STOPonにします。
SQLのファイルの先頭に\set ON_ERROR_STOP onを書くか、
psqlの実行時にpsql -v ON_ERROR_STOP=on -f ....のどちらかです。

マニュアル: https://www.postgresql.jp/document/11/html/app-psql.html

二点目のCSVの""をNULLで取り込む方法ですが、マニュアルにあるFORCE_NULLが使えそうですが、どうでしょう。(未確認)

https://www.postgresql.jp/document/11/html/sql-copy.html

投稿2020/01/31 02:41

bsdfan

総合スコア4560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saki_study111

2020/01/31 04:04

まさにやりたい事ができました! set ON_ERROR_STOP まではたどり着けたのですが FORCE_nullは見落としてました。 ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問