我有一张表,其中包含HDD上实际文件的相对路径。例如:
SELECT * FROM images -->
id | path
1 | /files/1.jpg
2 | /files/2.jpg
我可以创建一个查询来选择指向不存在的文件的所有记录吗?我需要完全通过MySql服务器检查它,而不使用PHP-client中的迭代。
答案 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_packet字节。如果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,就像使用任何内置函数一样。