【问题标题】:MySQL load data: This command is not supported in the prepared statement protocol yetMySQL 加载数据:prepared statement 协议尚不支持此命令
【发布时间】:2019-12-21 14:55:28
【问题描述】:

我正在尝试编写一个 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;

另外,我写了一个名为main.sh的bash脚本:

mysql -h "localhost" -u "root" "-pmypassword" "mydb" -e "set @spaceName=\"$1\";source update.sql;"

然后我执行./main.sh France.listFrance.list 是我尝试导入数据库的数据文件。

但是我得到一个错误:

ERROR 1295 (HY000) at line 2 in file: 'update.sql': 这个命令是 准备好的语句协议尚不支持

我发现了这个问题:
MySQL - Load Data Infile with variable path

那么,这是否意味着无法将参数传递给LOAD DATA 查询?

【问题讨论】:

    标签: mysql linux bash import parameter-passing


    【解决方案1】:

    您不能使用PREPARE 运行LOAD DATA INFILE

    您可以使用PREPARE 运行的语句列表记录在此页面中:https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html 在子标题“准备好的语句中允许的 SQL 语法”下。请注意,此列表在早期版本的 MySQL 中可能有所不同。

    因为你不能使用PREPARE,所以你不能通过设置变量和动态SQL语句来做你正在使用的方法。

    但是你可以运行LOAD DATA INFILE 而不使用PREPARE。您必须使用 shell 变量替换将文件名插入到语句中,然后将其作为直接 SQL 语句运行。

    您的 update.sql 文件可能如下所示:

    LOAD DATA LOCAL INFILE '%spacename%' INTO TABLE tmp 
    FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
    

    然后您可以将您的 shell 变量替换为文件并以这种方式运行结果:

    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”扩展名,因此您可以使用任何文件扩展名,也可以不使用。

    【讨论】:

    • Oracle 和 MySQL 很烂。你甚至不能USE @MY_DB_NAME; 或准备它。甲骨文应该为自己感到羞耻。
    • @jww 你能举一个允许它的另一个RDBMS的例子吗? USE 的参数是标识符,而不是字符串值。但会话变量和查询参数始终被视为值。在我所知道的任何品牌的 RDBMS 中,您不能在任何类型的 SQL 查询中使用会话变量或查询参数作为标识符。
    • 不,抱歉,我不能。我不是一个 SQL 人。我每三五年左右使用一次 SQL。但是,我可以为您提供允许您在 Hello World 程序中使用变量的其他语言的示例。 SQL 是我知道的唯一一种语言,你不能使用变量,必须做一些事情,比如准备它们(有时,直到它像现在一样中断)。
    • @jww 那么,您能否举一个强类型语言的示例,您可以在其中根据字符串变量中的函数或类的名称调用函数或实例化类?我知道 Java 中的反射和 PHP 中的变量以及类似的东西,但关键是它需要额外的代码或额外的语法,并且通常需要两步方法——就像 SQL 中的准备一样。
    • 我是说它不是任何 RDBMS 都支持的东西,因为它不是一个有意义的功能。您不能使用字符串作为标识符。大多数编译语言也是如此——您不能实例化像 new 'Classname'()new stringvar() 这样的对象,其中 stringvar 命名您要创建的类。
    【解决方案2】:

    如果您使用的是 Java 8+、Mysql 8.0+ 和 Connector/J 库 8.0.18,那么您可能会遇到“此版本不支持命令”或类似的问题。

    要解决此问题,您必须添加告诉preparedStatement 的属性来所有加载本地infile。你必须添加配置它,我在连接url中配置它并解决问题。

    jdbc:mysql://localhost:3306/tempDB?allowLoadLocalInfile=true
    

    我还对 my.cnf 文件进行了一些更改,例如:

    1. local_infile = 1

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 1970-01-01
      • 2013-07-03
      • 1970-01-01
      • 2019-08-16
      • 1970-01-01
      • 2019-05-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多