将 blob 插入 MySQL 数据库仅插入 NULL
Insert blob into MySQL database only inserts NULL
我尝试将一个 blob 从本地磁盘 (Windows 10) 插入到我的 RDS MySQL 数据库中。
但是我的查询不插入 blob。新行包含所有其他列,但 blob 为 NULL。
INSERT INTO table VALUES('c1', LOAD_FILE('C:/testing.7z'));
这是我尝试过的:
- 我设置了文件ro的权限read/write.
- secure_file_priv 设置为 /tmp ...我不知道这是什么意思。这是路径还是变量?如果它是一个变量,我已经尝试从 user/system 变量 "TMP" 的路径上传 blob 但没有成功。
我无法更改 secure_file_priv,因为 RDS 允许更改...如果它是一个路径,那么我必须从哪个路径上传文件?
- max_allowed_packet 设置为默认值(1024-1073741824 字节)。我的文件有 200 kb 大。
如何上传文件?
编辑:
我在我的本地数据库上尝试了相同的方法并且它有效 - 但仅适用于 select @@secure_file_priv;.
目录中的文件
根据 documentation,文件需要位于 secure_file_priv
中指定的目录中。因此,我建议您创建一个目录 c:/mysql-uploads
,更新 secure_file_priv
以指向该目录并将文件放在该目录中。我引用文档:
If the file does not exist or cannot be read because one of the preceding conditions is not satisfied, the function returns NULL.
更新
上述解决方案仅适用于文件位于数据库主机上的情况。由于您使用 AWS RDS,您无权访问本地文件系统,因此无论为 secure_file_priv
设置什么值,您都无法将文件复制到数据库主机。恐怕您将不得不使用客户端应用程序,它将使用客户端方法(即 JDBC)插入 content/blob。
您可以通过创建一个 Connection
和一个 PreparedStatement
来完成此操作,使用 setBinaryStream
将文件流加载到 blob 中,然后调用 executeUpdate
。完整示例:
Connection conn = DriverManager.getConnection(url,username,password);
String updateSQL = "INSERT INTO table VALUES(?,?)"
PreparedStatement pstmt = conn.prepareStatement(updateSQL);
File file = new File(filename);
FileInputStream input = new FileInputStream(file);
pstmt.setString(1, "c1");
pstmt.setBinaryStream(2, input);
pstmt.executeUpdate();
您正在插入 NULL
,因为文件必须与 服务器主机 相关,而不是发出查询的计算机。
查询是 text,它们不是函数,因此您无法执行从计算机读取文件并将其传输到服务器的查询。
您可以使用您熟悉的一种语言阅读文件并传输文件内容。
LOAD_FILE
的文档:https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_load-file
重要摘录:
To use this function, the file must be located on the server host, you
must specify the full path name to the file, and you must have the
FILE privilege.
我尝试将一个 blob 从本地磁盘 (Windows 10) 插入到我的 RDS MySQL 数据库中。 但是我的查询不插入 blob。新行包含所有其他列,但 blob 为 NULL。
INSERT INTO table VALUES('c1', LOAD_FILE('C:/testing.7z'));
这是我尝试过的:
- 我设置了文件ro的权限read/write.
- secure_file_priv 设置为 /tmp ...我不知道这是什么意思。这是路径还是变量?如果它是一个变量,我已经尝试从 user/system 变量 "TMP" 的路径上传 blob 但没有成功。 我无法更改 secure_file_priv,因为 RDS 允许更改...如果它是一个路径,那么我必须从哪个路径上传文件?
- max_allowed_packet 设置为默认值(1024-1073741824 字节)。我的文件有 200 kb 大。
如何上传文件?
编辑: 我在我的本地数据库上尝试了相同的方法并且它有效 - 但仅适用于 select @@secure_file_priv;.
目录中的文件根据 documentation,文件需要位于 secure_file_priv
中指定的目录中。因此,我建议您创建一个目录 c:/mysql-uploads
,更新 secure_file_priv
以指向该目录并将文件放在该目录中。我引用文档:
If the file does not exist or cannot be read because one of the preceding conditions is not satisfied, the function returns NULL.
更新
上述解决方案仅适用于文件位于数据库主机上的情况。由于您使用 AWS RDS,您无权访问本地文件系统,因此无论为 secure_file_priv
设置什么值,您都无法将文件复制到数据库主机。恐怕您将不得不使用客户端应用程序,它将使用客户端方法(即 JDBC)插入 content/blob。
您可以通过创建一个 Connection
和一个 PreparedStatement
来完成此操作,使用 setBinaryStream
将文件流加载到 blob 中,然后调用 executeUpdate
。完整示例:
Connection conn = DriverManager.getConnection(url,username,password);
String updateSQL = "INSERT INTO table VALUES(?,?)"
PreparedStatement pstmt = conn.prepareStatement(updateSQL);
File file = new File(filename);
FileInputStream input = new FileInputStream(file);
pstmt.setString(1, "c1");
pstmt.setBinaryStream(2, input);
pstmt.executeUpdate();
您正在插入 NULL
,因为文件必须与 服务器主机 相关,而不是发出查询的计算机。
查询是 text,它们不是函数,因此您无法执行从计算机读取文件并将其传输到服务器的查询。
您可以使用您熟悉的一种语言阅读文件并传输文件内容。
LOAD_FILE
的文档:https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function_load-file
重要摘录:
To use this function, the file must be located on the server host, you must specify the full path name to the file, and you must have the FILE privilege.