powershell スクリプトを使用して、csv ファイルから mysql データベースにデータを挿入しようとしています。LOAD DATA
クエリで (ダミー) 変数を使用すると、問題が発生します。
再現可能な例: Mysql データベースとテーブルを作成します。
CREATE DATABASE loadfiletest;
USE loadfiletest;
CREATE TABLE testtable (field1 INT, field2 INT DEFAULT 0);
loadfiletestdata.csv
含むという名前のcsvファイルを作成します
1,3
2,4
PowerShell スクリプトを作成します (db パスワードと場合によってはユーザー名を変更することを忘れないでください)。
[system.reflection.assembly]::LoadWithPartialName("MySql.Data")
$mysqlConn = New-Object -TypeName MySql.Data.MySqlClient.MySqlConnection
$mysqlConn.ConnectionString = "SERVER=localhost;DATABASE=loadfiletest;UID=root;PWD=pwd"
$mysqlConn.Open()
$MysqlQuery = New-Object -TypeName MySql.Data.MySqlClient.MySqlCommand
$MysqlQuery.Connection = $mysqlConn
$MysqlQuery.CommandText = "LOAD DATA LOCAL INFILE 'C:/path/to/files/loadfiletestdata.csv' INTO TABLE loadfiletest.testtable FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '""' LINES TERMINATED BY '\r\n' (field1, field2)"
$MysqlQuery.ExecuteNonQuery()
すべてをフォルダーに入れC:/path/to/files/
(powershell スクリプトのパスでもある必要があります)、スクリプトを実行します。これにより、テーブルtesttable
に
field1 field2
1 3
2 4
期待どおりです。これは、引用符などがそうあるべきであることを意味します。スクリプトが実行されるたびに、これらの値がテーブルに挿入されます。(field1, field2)
ここで、powershell スクリプトの最後の 1 行を に置き換える(field1, @dummy)
と、値が
field1 field2
1 0
2 0
表に挿入されます。ただし、エラーが表示されます
Exception calling "ExecuteNonQuery" with "0" argument(s): "Fatal error encountered during command execution."
At C:\path\to\files\loadfiletest.ps1:8 char:1
+ $queryOutput = $MysqlQuery.ExecuteNonQuery()
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : MySqlException
@dummy
mysql クライアントからクエリを実行すると、機能します。また、構文はmysqlマニュアルにあるものと同じように見えます(ページの途中で、 を探してください@dummy
)。
LOAD DATA
私が行ったさらにいくつかの実験では、変数を含むクエリでエラーが発生することが示唆されてい@whatever
ます。
質問:なぜうまくいかないのですか?LOAD DATA
powershell から (ダミー) 変数を使用してクエリを実行する方法はありますか? そうでない場合、エレガントな回避策はありますか?
明らかな回避策は、テーブルのレイアウトに従って中間 csv ファイルを作成するか、csv ファイルのレイアウトに一致する中間テーブルを作成することです。ただし、それは、私見が「うまくいく」はずの何かにとって、醜くて扱いにくいようです。
注: 現在の質問は、この質問のフォローアップと一般化です。古い内容を置き換えると既に与えられた回答が時代遅れになり、この質問の内容を追加すると古い質問が非常に長くなり、役に立たないサイドトラックがいっぱいになるため、新しい質問を開始することにしました。