MySQL中使用load data infile时遇到了访问被拒绝的问题。

129

我经常在PHP中使用MySQL查询,但是当我尝试在我的查询中使用变量时,就会出现问题。

LOAD DATA INFILE

我遇到了以下错误:

#1045 - 用户'user'@'localhost'被拒绝访问(使用密码:是)

有人知道这是什么意思吗?

12个回答

240

我也遇到了这个问题。我不得不在我的SQL语句中添加LOCAL

例如,以下代码将引发权限问题:

LOAD DATA INFILE '{$file}' INTO TABLE {$table}

在你的语句中添加LOCAL,权限问题应该就会消失。像这样:

LOAD DATA LOCAL INFILE '{$file}' INTO TABLE {$table}

16
这个功能有所不同。它会将你的文件上传到服务器上的一个临时目录。有时候这是必要的,但如果输入文件已经在MySQL服务器上,那么这只会造成冗余工作。 - jeffcook2150
1
是的,这对我很有帮助。我正在通过SSH转发数据库服务器端口,我猜它在远程数据库服务器上查找文件时没有LOCAL部分。 - mike
3
对我来说,这产生了以下错误:错误代码:1148 使用的命令与此MySQL版本不兼容。我尝试了一些解决此问题的答案,例如修改mysql文件为local-infile=1,但仍然失败了。 - OrwellHindenberg
6
你可能还需要使用 --local-infile 选项调用 mysql。 - shabbychef
1
请将以下与编程有关的内容从英语翻译成中文。仅返回已翻译的文本:同时,使用文件的绝对路径:/home/[currentuser]/filename - Mojtaba Pourmirzaei
显示剩余5条评论

40

我遇到了这个问题。我搜索了一下,但没有找到令人满意的答案。以下是我搜索结果的总结:

访问被拒绝的错误可能意味着:

  • 'user'@'localhost' 没有文件权限(GRANT FILE on *.* to user@'localhost'); 或者,
  • 你正在尝试加载的文件在运行 mysql 服务器的机器上不存在(如果使用 LOAD DATA INFILE); 或者,
  • 你正在尝试加载的文件不存在于本地机器上(如果使用 LOAD DATA LOCAL INFILE); 或者,
  • 你正在尝试加载的文件不可读(你需要文件和所有父目录都是可读的:chmod 755 directory; 和,chmod 744 file.dat)

+1:这对我有用:_您正在尝试加载的文件不是全局可读的(您需要将文件和所有父目录设置为全局可读:chmod 755 directory; 和 chmod 744 file.dat)_。我没有更改所有目录的权限。 - gavdotnet
2
用户Tatiana指出,您无法为每个数据库授予FILE权限,只能为整个服务器授予。授权命令应为“GRANT FILE on . to user@'localhost' IDENTIFIED BY 'password');”。 - JAL
5
@JAL 我想你的意思是“GRANT FILE ON *.* TO user ...”,可能星号字符被去掉了。请确认一下。 - Eugene M
正如 @Eugene M 所说,这会导致错误 DB GRANT 和 GLOBAL PRIVILEGES 的使用不正确 - Accountant م

21

尝试使用这个命令:

load data local infile 'home/data.txt' into table customer;

这应该可以运行。在我的情况下它起作用了。


3
错误 1148 (42000):此 MySQL 版本不允许使用该命令。 - Stewart
@Stewart,请从上述命令中删除“local”。当全局变量“local_infile”设置为“ON”时,较新的mysql版本似乎不支持此标志。因此,命令将是; mysql> load data infile 'home/data.txt' into table customer;+---------------+-------+ | Variable_name | Value | +---------------+-------+ | local_infile | ON | +---------------+-------+ - Kamran Hyder
@KamranHyder 听起来你的回答很好啊。为什么不把它作为完整的答案添加呢? - Stewart

11

确保你的MySQL用户被授予了FILE权限。

如果你正在使用共享Web托管服务,你的托管提供商可能会阻止该权限。


在共享 Web 托管上,使用“LOAD DATA LOCAL INFILE”是否有帮助? - Peter

7

如果您正在尝试在MySQL Workbench上进行此操作,

请前往连接 -> 编辑连接 -> 选择高级选项卡

并在“其他”文本字段中添加OPT_LOCAL_INFILE=1

现在重新启动连接并尝试。

输入图像描述


1
喜欢这个答案,因为它有屏幕截图,并指定了重新启动。 - behold

4

如果您正在使用命令行,则下面是一个简单的方法:

首先通过mysql -u[用户名] -p[密码] --local-infile命令登录。

然后执行命令SET GLOBAL local_infile = 1; 以启用本地文件加载功能。

选择要使用的数据库,可以通过use [数据库名]来实现。

最后,使用LOAD DATA LOCAL INFILE 'C:\\Users\\shant\\Downloads\\data-1573708892247.csv' INTO TABLE visitors_final_test FIELDS TERMINATED BY ','LINES TERMINATED BY '\r \n' IGNORE 1 LINES;将数据从CSV文件中加载到表中。请注意,这里保留了HTML标签且不进行解释。


添加 --local-inline 对我很有帮助。然而,在我的情况下,local_infile 全局变量已经设置为 ON。我认为用户最好在修改它之前先弄清楚他们在这个变量中写了什么值。 - Eugene Maysyuk
对于RDS用户 => 在RDS上添加--local-infile有所帮助,然而SET GLOBAL local_infile = 1;似乎在RDS上不起作用,但是即使没有那个命令,--local-infile也可以解决问题。 - Fact

3

来自里昂的字符串给了我一个非常好的提示:在Windows中,我们需要使用斜杠而不是反斜杠。这段代码对我有效:

    File tempFile = File.createTempFile(tableName, ".csv");
    FileUtils.copyInputStreamToFile(data, tempFile);

    JdbcTemplate template = new JdbcTemplate(dataSource);
    String path = tempFile.getAbsolutePath().replace('\\', '/');
    int rows = template.update(MessageFormat
            .format("LOAD DATA LOCAL INFILE ''{0}'' INTO TABLE {1} FIELDS TERMINATED BY '',''",
                    path, tableName));
    logger.info("imported {} rows into {}", rows, tableName);

    tempFile.delete();

2

2

我也遇到了这个问题,尽管我按照Yamir在他的帖子中描述的所有步骤进行操作,但仍然无法使其正常工作。

该文件位于/tmp/test.csv,权限为777。MySQL用户具有文件权限,我的MySQL版本不允许LOCAL选项,所以我被卡住了。

最终,我通过运行以下命令解决了问题:

sudo chown mysql:mysql /tmp/test.csv

0

我发现加载MySQL表可以快速且无痛(我使用的是Python / Django模型管理器脚本):

1)创建具有所有列VARCHAR(n)NULL的表,例如:

mysql> CREATE TABLE cw_well2( api VARCHAR(10) NULL,api_county VARCHAR(3) NULL);


 2)从CSV中删除标题(第一行),然后加载(如果您忘记了LOCAL,则会收到“#1045-用户'user'@'localhost'(使用密码:YES)拒绝访问”):

mysql> LOAD DATA LOCAL INFILE "/home/magula6/cogswatch2/well2.csv" INTO TABLE cw_well2 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'     -> ; Query OK, 119426 rows affected, 19962 warnings  (3.41 sec)


 3)更改列:

mysql> ALTER TABLE cw_well2 CHANGE spud_date spud_date DATE;

mysql> ALTER TABLE cw_well2 CHANGE latitude latitude FLOAT;

完成!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接