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

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

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

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

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

SQL

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

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

2回答

9359閲覧

PostgreSQLのCOPYコマンドのファイルパスを変数で渡す方法について

L.J

総合スコア2

PostgreSQL

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

PL/SQL

PL/SQL (Procedural Language/Structured Query Language) はOracle CorporationによるSQL(非手続き型言語)を手続き型言語に拡張させるために開発されたプログラミング言語です。

SQL

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

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

1クリップ

投稿2021/11/01 02:35

編集2021/11/03 03:08

初めてテラテイルを利用させていただきます、質問方法に不備がありましたら申し訳ございません。

前提・実現したいこと

PowerShell(.ps1ファイル)から PostgreSQL(.sqlファイル)に変数を渡してCOPYコマンドを実行したい。

■ファイル構成
. D:\SQLTEST
.  ├ POWERSHELL
.  │ └ TEST.ps1
.  ├ SQL
.  │ └ TEST.sql
.  └ CSV
.   └ TEST.csv

発生している問題・エラーメッセージ

psql : unrecognized win32 error code: 123psql:D:/SQLTEST/SQL/TEST.sql:20: error: :: Invalid argument

該当のソースコード

■TEST.ps1

PowerShell

1 2$SQLF = "D:\SQLTEST\SQL\TEST.sql" 3$CSVDIR = "D:\SQLTEST\CSV" 4 5(以下はサンプルのため適当です。) 6$HOSTNAME = "HOST" 7$DBUSER = "DBUSER" 8$PORT = "99999" 9$DBNAME = "DBNAME" 10 11psql -w -a -h $HOSTNAME -U $DBUSER -p %PORT -d $DBNAME -f $SQLF -v CSVDIR="${CSVDIR}"

■TEST.sql

PostgreSQL

1\copy TEST_TABLE from ':CSVDIR\TEST.CSV' with encoding 'sjis' csv;

PowerShellからpsqlコマンドでPostgreSQLに接続し、
-v オプションで CSVDIRという変数に "D:\SQLTEST\CSV" を入れてsqlファイルに渡しています。

実際のファイルパスは"D:\SQLTEST\CSV\TEST.csv"のため、
sqlファイルのほうで ':CSVDIR\TEST.CSV' と記載しましたが、上手くいきません。

何か対処法等ございましたら、ご教示いただけますと幸いです。
よろしくおねがいいたします。

補足情報(FW/ツールのバージョンなど)

PostgreSQL 12.4

2021/11/03 追記

あれから色々とご指摘をいただきながら自分で試してみまして、
posgresql \copyのfromに変数(csvのパス)を使いたい
上記を参考に、COPYコマンド自体を変数にセットしてみました。

■TEST.sql

SQL

1\set filepass :CSVDIR'\TEST.CSV'; 2 3-- 変数の中身確認 4\echo :filepass 5 6\set copycmd '\copy TEST_TABLE from ':filepass' with encoding ''sjis'' csv;' 7 8-- \copyコマンド実行 9:copycmd

実行結果

SQL

1-- 変数の中身確認 2\echo :filepass 3 4D:\SQLTEST\CSV\TEST.CSV -- ちゃんとファイルパスがセットされている 5 6-- \copyコマンド実行 7:copycmd 8 9psql : psql:D:/SQLTEST/SQL/TEST.sql:42: ERROR: syntax error at or near "'sjis'" 10

なぜ 'sjis' がsyntax errorになったのかは不明ですが、
filepassのエラーは解消されたのかな?と思っています…。引き続き調べています

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

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

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

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

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

guest

回答2

0

ベストアンサー

こんな感じではどうでしょうか。

psql

1\copy TEST_TABLE from :'CSVDIR' || '\TEST.CSV' with encoding 'sjis' csv;

投稿2021/11/02 08:26

sazi

総合スコア25327

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

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

L.J

2021/11/03 02:24

ご回答いただきありがとうございます。 試してみたのですが、やはり同じエラーが出てしまいました…。
sazi

2021/11/03 03:30

取り敢えず、SQLファイルを分離して、PowerShellでpsql の-cオプションで直接\copyだけ実行するというのは駄目ですか?
sazi

2021/11/03 03:50 編集

追記を見落としていました。 \set copycmd "\copy TEST_TABLE from " :filepass " with encoding 'sjis' csv;" としてみてはどうでしょうか。
sazi

2021/11/03 03:55 編集

追記の記述で変数が参照できているなら \copy TEST_TABLE from :CSVDIR || '\TEST.CSV' with encoding 'sjis' csv; だったらどうですか。
L.J

2021/11/03 05:05

ご回答いただきありがとうございます。 >\set copycmd "\copy TEST_TABLE from " :filepass " with encoding 'sjis' csv;" >としてみてはどうでしょうか。 こちらですが、 error: invalid command \SQLTEST となりました。 (なぜ D: が無視されたのかわかりませんでした…) >追記の記述で変数が参照できているなら >\copy TEST_TABLE from :CSVDIR || '\TEST.CSV' with encoding 'sjis' csv; こちらも試してみましたが、 error: :CSVDIR||: No such file or directory となりました。 :CSVDIR が変数として展開されず文字列として扱われているように見えます…。 いろいろとご教示いただいたのに申し訳ございません…。
sazi

2021/11/03 06:14 編集

:CSVDIR'\TEST.CSV' ではどうですか 試してはいないので、またエラーになるかもしれませんが
L.J

2021/11/03 08:34

ご回答いただきありがとうございます。 >:CSVDIR'\TEST.CSV' >ではどうですか error: :CSVDIR||: No such file or directory となりました。 上記と同じく、:CSVDIR が変数として展開されず文字列として扱われているようです…。
sazi

2021/11/03 08:42 編集

「:CSVDIR'\TEST.CSV'」であれば、「:CSVDIR||」というようにエラーに「||」が含まれるないと思うのですが。エラー時に文字結合を「||]に変換しているとは考えにくいですし。 修正が反映されていないのでは? 修正が正しいのなら、変数が参照されていないという事になりますね。 それから、-cオプションは試されました?
L.J

2021/11/03 11:52

ありがとうございます。 >「:CSVDIR'\TEST.CSV'」であれば、「:CSVDIR||」というようにエラーに「||」が含まれるないと思うのですが。エラー時に文字結合を「||]に変換しているとは考えにくいですし。 修正が反映されていないのでは? 申し訳ございません、こちらエラーコードのコピーが前のものが残っておりまして、正しくは下記になります。 error: :CSVDIR: No such file or directory -cオプションについてですが、TEST.sqlにはcopyコマンドの他にもいろいろ記述しておりまして、(省略していました)ワンラインでは実行できそうにないためSQLファイルで実行しておりました…。
sazi

2021/11/04 14:59 編集

変数をSQLファイル上で参照できるのは確認できているのですよね。 それなのに取得できないというのは、何か取得できている時と違うんじゃないですか? それから、COPYだけ-cで実行した後に、残りをSQLファイルで行うというのも駄目なんですね。
L.J

2021/11/17 11:01

sazi様 病院にお世話になる用事があり、返信がとても遅れてしまい、大変申し訳ございませんでした。 あれから色々と試しまして、最終的に以下の記述で上手くいきました。 ────────────────────────── \set filepass :CSVDIR'\TEST.CSV' \set copycmd '\copy TEST_TABLE from ' :filepass ' with encoding ''sjis'' csv;' :copycmd ────────────────────────── 色々とご教授いただきとても助かりました。 ありがとうございました。
sazi

2021/11/17 13:53

\のエスケープが問題だったという訳ですね。
guest

0

PowerShell上では、「\」→「\」としないといけないかと。
正規表現:エスケープが必要な文字一覧 | WWWクリエイターズ

$SQLF = "D:\SQLTEST\SQL\TEST.sql" $CSVDIR = "D:\SQLTEST\CSV"

ですが、SQLファイルの中でPowerShellの変数を展開するのは無理がありますので、
psqlの\setメタコマンドで変数に格納し、 \set foo bar などとしたなら、
参照するには SQL文中で :foo などとすることで展開されますので、
こちらを応用するとよろしいかと。
psql
高度な機能
変数

SQL差し替え
の項目をご覧ください。

投稿2021/11/02 01:21

編集2021/11/02 07:38
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

L.J

2021/11/02 04:28

ご回答いただきありがとうございます。 試しに、手元の環境で ':CSVDIR\TEST.CSV' としてみましたが、同様のエラーが出てしまいました…。 わざわざご回答いただいたのに申し訳ございません。 引き続き調べてみます…。
退会済みユーザー

退会済みユーザー

2021/11/02 07:35

SQLファイルの中でPowerShell変数展開させよう、というのはそもそも無理なのでは。 $SQLF = "D:\SQLTEST\SQL\TEST.sql" $CSVDIR = "D:\SQLTEST\CSV" とPowerShell内では表記する必要があります、という点だけ申し述べさせていただきます。 TEST.sql を別途動的生成してみるほうがいいでしょうね。 psql上で実行するだけのSQLファイルだとしたら、 \i メタコマンドで外部ファイルを読み込んで実行することができるので、 psql上の変数に代入させるような内容のSQLを記述しておくという方法が考えられます。 psqlの\setメタコマンドで変数に格納し、 \set foo bar などとしたなら、 参照するには SQL文中で :foo などとすることで展開されますので。 https://www.postgresql.jp/document/13/html/app-psql.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問