Reputation: 1133
I am working on trying to automate the following process:
I have step one working just fine, but step 2 has been giving me some issues. I think I am having some problems with my syntax but i can't figure out that I'm doing wrong. Here is the PowerShell script I am using:
[System.Reflection.Assembly]::LoadWithPartialName("MySql.Data")
$mysqlConn = New-Object -TypeName MySql.Data.MySqlClient.MySqlConnection
$mysqlConn.ConnectionString = "SERVER=****.net;DATABASE=****;UID=****;PWD=****"
$mysqlConn.Open()
$MysqlQuery = New-Object -TypeName MySql.Data.MySqlClient.MySqlCommand
$MysqlQuery.Connection = $mysqlConn
$MysqlQuery.CommandText = "LOAD DATA LOCAL INFILE 'C:\Users\Lucy\Documents\FTPFiles\vc_report_20171211.csv' INTO TABLE campaigns IGNORE 1 LINES"
$MysqlQuery.ExecuteNonQuery()
and here is the error that I am receiving:
Exception calling "ExecuteNonQuery" with "0" argument(s): "Fatal error encountered during command execution." At C:\Users\Lucy\Documents\FTPFiles\upload.ps1:8 char:1 + $MysqlQuery.ExecuteNonQuery() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : MySqlException
Upvotes: 1
Views: 1237
Reputation: 200373
You're getting that error because you got the path separator wrong. The backslash is an escape character in MySQL queries, so you need to escape the backslashes with another backslash (to get a literal backslash in the query):
LOAD DATA LOCAL INFILE 'C:\\path\\to\\your.csv'
INTO TABLE campaigns
IGNORE 1 LINES
or use forward slashes:
LOAD DATA LOCAL INFILE 'C:/path/to/your.csv'
INTO TABLE campaigns
IGNORE 1 LINES
However, that alone won't make the import succeed. You also need to specify the proper terminators so that the CSV records and fields are recognized on import:
LOAD DATA LOCAL INFILE 'C:/path/to/your.csv'
INTO TABLE suppliers
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES
Change the line terminator to just \n
if your files have line breaks encoded as LF (unix-style) rather than CR-LF (windows-style). Also, you need to escape the double quote in the ENCLOSED BY
clause with a backtick when defining the statement as a PowerShell string:
$MysqlQuery.CommandText = "LOAD DATA ... ENCLOSED BY '`"' ... IGNORE 1 LINES"
# ^
Without these additional clauses the default values would be used, which would cause an incorrect or failed import, depending on your table definition.
From the documentation:
If you specify no
FIELDS
orLINES
clause, the defaults are the same as if you had written this:FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' STARTING BY ''
Importing a local file to a remote server normally shouldn't be the cause of this issue, as you already suspected, because the LOCAL
keyword instructs the client to send the file to the server for import.
From the documentation:
The
LOCAL
keyword affects expected location of the file and error handling, as described later.LOCAL
works only if your server and your client both have been configured to permit it. For example, ifmysqld
was started with thelocal_infile
system variable disabled,LOCAL
does not work. See Section 6.1.6, “Security Issues with LOAD DATA LOCAL”.The
LOCAL
keyword affects where the file is expected to be found:
If
LOCAL
is specified, the file is read by the client program on the client host and sent to the server. The file can be given as a full path name to specify its exact location. If given as a relative path name, the name is interpreted relative to the directory in which the client program was started.When using
LOCAL
withLOAD DATA
, a copy of the file is created in the server's temporary directory. This is not the directory determined by the value oftmpdir
orslave_load_tmpdir
, but rather the operating system's temporary directory, and is not configurable in the MySQL Server. (Typically the system temporary directory is/tmp
on Linux systems andC:\WINDOWS\TEMP
on Windows.) Lack of sufficient space for the copy in this directory can cause theLOAD DATA LOCAL
statement to fail.
Upvotes: 1