我正在尝试编写一个mysql脚本以将数据导入我的Linux服务器的表。这是名为 update.sql
的脚本:
SET @query = CONCAT("LOAD DATA LOCAL INFILE '", @spaceName, "' INTO TABLE tmp FIELDS TERMINATED BY ',' LINES TERMINATED BY 'n';");
PREPARE stmt FROM @query;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
,而且,我写了一个bash脚本,名为 main.sh
:
mysql -h "localhost" -u "root" "-pmypassword" "mydb" -e "set @spaceName="$1";source update.sql;"
然后我执行./main.sh France.list
。France.list
是我要导入到数据库的数据文件。
但是我有一个错误:
错误1295(hy000(在文件2中的第2行:'update.sql':此命令是 准备好的语句协议中不支持
我发现了这个问题:
mysql-加载数据流动,带有可变路径
那么,这是否意味着没有办法将参数传递给LOAD DATA
查询?
您不能使用PREPARE
运行LOAD DATA INFILE
。
在此页面中记录了可以使用PREPARE
运行的语句列表:https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-preprepared-statements.html在子标题下SQL语法在准备好的语句中允许"。注意此列表在MySQL的早期版本中可能有所不同。
因为您无法使用PREPARE
,所以您无法通过设置变量并制作动态SQL语句来执行您使用的方法。
但是您可以在不使用PREPARE
的情况下运行LOAD DATA INFILE
。您必须使用shell变量替换将文件名插入语句中,然后将其作为直接SQL语句运行。
您的update.sql文件可能看起来像:
LOAD DATA LOCAL INFILE '%spacename%' INTO TABLE tmp
FIELDS TERMINATED BY ',' LINES TERMINATED BY 'n';
然后,您可以将外壳变量替换到文件中并以此方式运行结果:
sed s/%spacename%/$1/ update.sql |
mysql -h "localhost" -u "root" "-pmypassword" "mydb"
另一种简单的方法是使用MySqlimport,只是要求输入文件名与您的表名称相同。您可以重命名输入文件以匹配要加载到的表(您调用tmp
(,或者创建一个符号链接:
ln -s $1 /tmp/tmp.list
mysqlimport --local -h "localhost" -u "root" "-pmypassword" "mydb" /tmp/tmp.list
rm -f /tmp/tmp.list
MySqlimport忽略了" .list"扩展名,因此您可以使用任何文件扩展名,也可以无。
如果您使用的是Java 8 ,MySQL 8.0 和Connector/j Library 8.0.18,那么您可能会遇到此问题,例如"命令不受此版本不支持"或其他内容或类似。
要解决该问题,您必须添加属性,该属性将准备准备的所有加载本地流动。您必须添加配置,我将其配置为连接URL并解决问题。
jdbc:mysql://localhost:3306/tempDB?allowLoadLocalInfile=true
我在.cnf文件中也进行了一些更改,例如:
- local_infile = 1