问题
I have a table that holds relative paths to real files on HDD. for example:
SELECT * FROM images -->
id | path
1 | /files/1.jpg
2 | /files/2.jpg
Can I create a query to select all records pointing to non-existent files? I need to check it by MySql server exactly, without using an iteration in PHP-client.
回答1:
I would go with a query like this:
SELECT id, path, ISNULL(LOAD_FILE(path)) as not_exists
FROM images
HAVING not_exists = 1
The function LOAD_FILE
tries to load the file as a string, and returns NULL
when it fails.
Please notice that a failure in this case might be due to the fact that mysql simply cannot read that specific location, even if the file actually exists.
EDIT:
As @ostrokach pointed out in comments, this isn't standard SQL, even though MySQL allows it, to follow the standard it could be:
SELECT *
FROM images
WHERE LOAD_FILE(PATH) IS NULL
回答2:
MYSQL only handles the Database so there is no way for you to fire an SQL Statement to check on the HDD if the file exists. You need to iterate over the rows and check it with PHP.
回答3:
The MySQL LOAD_FILE
command has very stringent requirements on the files that it can open. From the MySQL docs:
[
LOAD_FILE
] Reads the file and returns the file contents as a string. 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. The file must be readable by all and its size less than max_allowed_packet bytes. If the secure_file_priv system variable is set to a non-empty directory name, the file to be loaded must be located in that directory.
So if the file can't be reached by the mysql
user or any of the other requirements are not satisfied, LOAD_FILE
will return Null
.
You can get a list of IDs that correspond to missing files using awk
:
mysql db_name --batch -s -e "SELECT id, path FROM images" \ | awk '{if(system("[ -e " $2 " ]") == 1) {print $1}}' \ >> missing_ids.txt
or simply using bash
:
mysql db_name --batch -s -e "SELECT id, path FROM images" \ | while read id path ; if [[ -e "$path" ]] ; then echo $id ; done >> missing_ids.txt
This also has the advantage of being much faster than LOAD_FILE
.
回答4:
It's not possible using stock MySQL. However you can write UDF (user-defined function), probably in C, load it using CREATE FUNCTION statement and use it from MySQL as you would use any built-in function.
来源:https://stackoverflow.com/questions/17192827/can-mysql-check-that-file-exists