MySQL可以检查该文件是否存在?

时间:2013-06-19 13:41:54

标签: mysql file-exists

我有一张表,其中包含HDD上实际文件的相对路径。例如:

SELECT * FROM images -->
id | path
1  | /files/1.jpg
2  | /files/2.jpg

我可以创建一个查询来选择指向不存在的文件的所有记录吗?我需要完全通过MySql服务器检查它,而不使用PHP-client中的迭代。

4 个答案:

答案 0 :(得分:10)

我会选择这样的查询:

SELECT id, path, ISNULL(LOAD_FILE(path)) as not_exists
FROM images
HAVING not_exists = 1

函数LOAD_FILE尝试将文件作为字符串加载,并在失败时返回NULL

请注意,在这种情况下失败的原因可能是mysql根本无法读取该特定位置,即使该文件确实存在。

编辑:

正如@ostrokach在评论中指出的那样,即使MySQL允许,这也不是标准的SQL,它遵循的标准可能是:

SELECT *
FROM images
WHERE LOAD_FILE(PATH) IS NULL

答案 1 :(得分:3)

MYSQL仅处理数据库,因此如果文件存在,则无法触发SQL语句来检查HDD。您需要遍历行并使用PHP进行检查。

答案 2 :(得分:3)

MySQL LOAD_FILE命令对它可以打开的文件有非常严格的要求。来自MySQL文档:

  

[LOAD_FILE]读取文件并以字符串形式返回文件内容。要使用此功能,文件必须位于服务器主机上,您必须指定文件的完整路径名,并且您必须具有FILE权限。该文件必须可由所有人读取,其大小必须小于max_allowed_pa​​cket字节。如果secure_file_priv系统变量设置为非空目录名,则要加载的文件必须位于该目录中。

因此,如果mysql用户无法访问该文件,或者不满足任何其他要求,LOAD_FILE将返回Null

您可以使用awk获取与丢失文件相对应的ID列表:

mysql db_name --batch -s -e "SELECT id, path FROM images" \
    | awk '{if(system("[ -e " $2 " ]") == 1) {print $1}}' \
    >> missing_ids.txt

或仅使用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

这也具有比LOAD_FILE快得多的优势。

答案 3 :(得分:0)

使用MySQL库存是不可能的。但是,您可以编写UDF(用户定义的函数),可能在C中,使用CREATE FUNCTION语句加载它,并使用MySQL,就像使用任何内置函数一样。