GVKun编程网logo

Mysql 命令 load data infile 权限问题(mysql load_file)

5

对于想了解Mysql命令loaddatainfile权限问题的读者,本文将提供新的信息,我们将详细介绍mysqlload_file,并且为您提供关于java–JDBC:CSV原始数据使用流从/向远程M

对于想了解Mysql 命令 load data infile 权限问题的读者,本文将提供新的信息,我们将详细介绍mysql load_file,并且为您提供关于java – JDBC:CSV原始数据使用流从/向远程MySQL数据库导出/导入(SELECT INTO OUTFILE / LOAD DATA INFILE)、JPA 通过 LOAD DATA LOCAL INFILE 大批量导入数据到 MySQL、LOAD DATA INFILE、LOAD DATA INFILE INTO TABLE的有价值信息。

本文目录一览:

Mysql 命令 load data infile 权限问题(mysql load_file)

Mysql 命令 load data infile 权限问题(mysql load_file)

【1】Mysql命令load data infile 执行权限问题

工作中,经常会遇到往线上环境mysql数据库批量导入源数据的场景。

针对这个场景问题,mysql有一个很高效的命令:load data infile

通过load data infile命令将data_file文件数据导入表中。

当然,因为mysql数据库权限限制的问题,分为以下几种情况:

(1)root用户(特指mysql的root,非Linux系统的root)

在mysql server部署机器通过load data infile命令导入数据时,只要文件路径指定正确,一般不会有问题。

如果导入失败,请参见随笔《Mysql 导入文件提示 --secure-file-priv option 问题》

(2)非root用户在mysql server部署机器通过load data infile命令导入数据时,报错:

ERROR 1045 (28000): Access denied for user ''xxx''@''xxx'' (using password: YES)

这个错误一般是因为非root用户没有FILE Privilege权限,查询当前用户权限可参见随笔《Mysql 用户及权限》

两种解决方案:

[1] 命令加local参数。用load data local infile ''filename'' into table 来导入数据(强烈推荐使用)

[2] 为当前用户开通权限。给当前用户开通FILE Privilege权限时,注意:

FILE权限与SELECE/DELETE/UPDATE等不同,后者是可以具体指定到某个db的某个表的,而FILE则是全局的,

即只能通过grant FILE on *.* to ''abcde''@''%''才能使FILE权限对所有db的所有tables生效。

通过grant all on db.* to ''abcde''@''%''不能使指定的user在指定的db上具有FILE权限。

根据最小权限原则(操作系统安全的概念),这个方法并不安全,故不推荐使用。

(3)非root用户从client机器load data local infile至remote mysql server时,报错:

ERROR 1148 (42000): The used command is not allowed with this MySQL version

可能原因(from mysql reference manual):

If LOAD DATA LOCAL is disabled, either in the server or the client, a client that attempts to issue such a statement receives the following error message:

ERROR 1148: The used command is not allowed with this MySQL version

可见,出于安全考虑,默认是不允许从client host远程通过load data命令导数据的

解决办法:

For the mysql command-line client, enable LOAD DATA LOCAL by specifying the --local-infile[=1]option, or disable it with the --local-infile=0 option

也即,在需要从client host导人数据的场景下,当登陆mysql时,需用--local-infile[=1]显式指定参数,典型命令形式为:

mysql --local-infile -u user -p passwd

登陆成功后,再执行load data infile ''filename'' into table即可。

 

Good Good Study, Day Day Up.

顺序 选择 循环 总结

java – JDBC:CSV原始数据使用流从/向远程MySQL数据库导出/导入(SELECT INTO OUTFILE / LOAD DATA INFILE)

java – JDBC:CSV原始数据使用流从/向远程MySQL数据库导出/导入(SELECT INTO OUTFILE / LOAD DATA INFILE)

我正在开发的Web应用程序支持CSV导出(使用SELECT INTO OUTFILE)并导入(使用LOAD DATA INFILE)MySQL服务器来维护庞大的数据集,这些数据集在Java代码中使用SELECT和批量INSERT语句进行处理非常昂贵(处理结果集,字符串编码,业务逻辑遗产等).这些CSV文件不是应用程序驱动的,因此它们只代表MysqL数据库中的原始表内容.但据我所知,这种方法只有在我有本地文件时才有用,所以web应用服务器和MysqLd都必须在同一台机器上运行.

应用程序配置可以指定远程数据库连接.这显然意味着上传的CSV文件存储在运行Web应用程序的机器本地的某处,因此我无法在MysqL LOAD DATA INFILE语句中指定数据文件位置. (相同的方案是CSV下载请求).所以,我想要找到的是一种“虚拟”指定CSV文件的方法 – 使用可由JDBC和MysqL处理的I / O流,类似于blob管理等.

JDBC / MysqL是否支持这种用于导入和导出的CSV文件的技术?

提前致谢.

最佳答案
您可以使用LOCAL选项运行LOAD DATA INFILE,然后使用com.MysqL.jdbc.Statement #setLocalInfileInputStream从运行MysqL JDBC客户端的位置加载CSV文件.例如:

// conn is an existing java.sql.Connection to a Remote Server
try (Statement st = conn.createStatement()) {
    String localCsvFileSpec = "C:/Users/Jamie/Desktop/foo.csv";  // on this machine
    ((com.MysqL.jdbc.Statement) st).setLocalInfileInputStream(
            new FileInputStream(localCsvFileSpec));
    st.execute(
            "LOAD DATA LOCAL INFILE '(placeholder)' " + 
            "INTO TABLE table01 " +
            "COLUMNS TERMINATED BY ',' " +
            "(id,txt) " + 
            "");
}

有关更多信息,请参见this post.

不幸的是,从this answer on Stack Overflow开始,您似乎无法使用SELECT INTO OUTFILE将文件导出到数据库服务器以外的任何位置.

JPA 通过 LOAD DATA LOCAL INFILE 大批量导入数据到 MySQL

JPA 通过 LOAD DATA LOCAL INFILE 大批量导入数据到 MySQL

连接层代码:

import org.hibernate.Session;
import org.hibernate.internal.SessionFactoryImpl;
import org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public int loadFromInputStream(String loadDataSql, InputStream dataStream) throws JPAException {
		Session session = (Session) entityManagerFactory.getDelegate();
		SessionFactoryImpl sessionFactory = (SessionFactoryImpl) session.getSessionFactory();
		int result = 0;
		try {
			//获取C3P0连接
			Connection conn = sessionFactory.getConnectionProvider().getConnection();
			PreparedStatement ps = conn.prepareStatement(loadDataSql);
			//将C3P0的连接转换成mysql的
			C3P0NativeJdbcExtractor cp30NativeJdbcExtractor = new C3P0NativeJdbcExtractor();  
			com.mysql.jdbc.Connection mysql_conn = (com.mysql.jdbc.Connection) cp30NativeJdbcExtractor.getNativeConnection(ps.getConnection());
			//将C3P0的PreparedStatement转换成mysql的
			com.mysql.jdbc.PreparedStatement mysql_ps = mysql_conn.prepareStatement(loadDataSql).unwrap(com.mysql.jdbc.PreparedStatement.class);
			//设置文件流
			mysql_ps.setLocalInfileInputStream(dataStream);
			result = ps.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}

使用连接层代码:

public void testLoadFile() throws ServiceException {
		String loadDataSql = "load data LOCAL infile ''C:/Users/Administrator/Desktop/userinfo.txt'' into table userinfo character set utf8 fields terminated by '','' enclosed by ''\"'' lines terminated by ''\r\n'' (`userId`,`userName`,`userNickName`,`createTime`,`userEmail`,`userPassword`,`userSex`,`userMobile`,`lastLoginTime`);";
		byte[] bytes = loadDataSql.getBytes();  
        InputStream is = new ByteArrayInputStream(bytes);  
		try {
			userDAO.testLoadFile(loadDataSql, is);
		} catch (JPAException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

userinfo.txt 内容:

"2","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"3","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"4","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"5","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"6","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"7","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"8","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"9","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"10","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"11","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"12","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"13","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"14","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"15","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"16","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"
"17","2","2","2017-01-13 14:03:53","2","2","2","2","2017-01-13 14:03:53"

userinfo 表结构:

CREATE TABLE `userinfo` (
  `userId` varchar(36) NOT NULL,
  `userName` varchar(45) DEFAULT NULL,
  `userNickName` varchar(45) DEFAULT NULL,
  `createTime` datetime DEFAULT NULL,
  `userEmail` varchar(45) DEFAULT NULL,
  `userPassword` varchar(45) DEFAULT NULL,
  `userSex` int(11) DEFAULT NULL,
  `userMobile` varchar(45) DEFAULT NULL,
  `lastLoginTime` datetime DEFAULT NULL,
  PRIMARY KEY (`userId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

LOAD DATA INFILE

LOAD DATA INFILE

IGNORE INTO TABLE tableName  ---指定导入表
fields terminated by '',''---按,分割文件
ENCLOSED BY ''\"'' ---替换"
(`uid`,`ecoin`,`type`)----指定导入列明, 




LOAD DATA INFILE INTO TABLE

LOAD DATA INFILE INTO TABLE

LOAD DATA INFILE  ''G:/wamp2/bin/mysql/mysql5.5.24/outfile/pos.txt''
INTO TABLE
pos
(
  
    Id
    , code
    , name
    , BAmt
    , SAmt
    , wBP
    , wSP
    , wBM
    , wSM

)

---------

不用 GUI,好写入程序

我们今天的关于Mysql 命令 load data infile 权限问题mysql load_file的分享已经告一段落,感谢您的关注,如果您想了解更多关于java – JDBC:CSV原始数据使用流从/向远程MySQL数据库导出/导入(SELECT INTO OUTFILE / LOAD DATA INFILE)、JPA 通过 LOAD DATA LOCAL INFILE 大批量导入数据到 MySQL、LOAD DATA INFILE、LOAD DATA INFILE INTO TABLE的相关信息,请在本站查询。

本文标签: