简体   繁体   English

删除SQL数据库中不存在的图像

[英]Delete images that don't exist in SQL database

I have a table of products in my sql database. 我的sql数据库中有一个产品表。 Each product has an image and 4 thumbnails. 每个产品都有一个图像和4个缩略图。 These just store the filename of an image on the hard drive. 这些只是将图像的文件名存储在硬盘上。 The problem I have is that over time I have deleted thousands of products but the images still remain on the hard drive. 我遇到的问题是,随着时间的推移,我删除了数千种产品,但图像仍然保留在硬盘上。

Now I need to build a script (in c# .net) to remove any orphaned images. 现在我需要构建一个脚本(在c#.net中)来删除任何孤立的图像。 I assume the only way is to get a list of products into memory and loop though all the images in the directory to cross reference and remove if they don't exist. 我假设唯一的方法是将产品列表放入内存并循环通过目录中的所有图像进行交叉引用,如果它们不存在则删除。

Has anyone come across this before and can you give me any advice? 有没有人遇到过这个问题,你能给我任何建议吗?

A quicker way would be to write a procedure that moves all the images that are referenced to a new folder on the same hard drive. 更快的方法是编写将所有引用到一个新的文件夹相同的硬盘驱动器上的图像的过程。 Then once you've verified you've got them all delete (or rename if you're feeling nervous) the old folder and finally rename the new one back to the original name. 然后,一旦你确认你已经将它们全部删除(或者如果你感到紧张则重命名)旧文件夹,最后将新文件重命名为原始名称。

You should backup the original folder first, just in case. 您应首先备份原始文件夹,以防万一。

An idea comes to mind: Can you somehow flag the images that you DO need? 想到一个想法:你能以某种方式标记你需要的图像吗? In the most basic way you could rename them temporarily to lets say used_xxx.jpg 在最基本的方式,你可以临时重命名它们让我们说used_xxx.jpg

Then cursively loop your folders and delete all the images that dont have the used_ prefix. 然后大量循环你的文件夹并删除所有没有used_前缀的图像。 After that you rename back the still existing images to their original names. 之后,将现有图像重命名为原始名称。

Edit: This way you wouldn't have to copy anything. 编辑:这样你就不必复制任何东西了。 And you have a visual reference so you can see what you're doing. 你有一个视觉参考,所以你可以看到你在做什么。

That really is the only way you would do it. 这真的是你唯一能做到的。 I would suggest first iterating through the product images in the database and build a List<string> with their names and paths, then use the Directory object to pull a list of all images, recursively if necessary, in your images directory. 我建议首先遍历数据库中的产品图像并使用它们的名称和路径构建List<string> ,然后使用Directory对象在图像目录中以递归方式提取所有图像的列表。

Then go through each file in the returned listing and compare it with your List<string> . 然后浏览返回列表中的每个文件,并将其与List<string>进行比较。 If it doesn't exist in the list, delete it off the filesystem. 如果列表中不存在,请将其从文件系统中删除。

Remember to back up, just in case! 记得备份,以防万一!

您似乎已经回答了自己的问题...而不是遍历目录中的所有图像,您可以迭代数据库中的所有产品,并且每个产品将图像复制到新文件夹,但它几乎相同事情。

If you're familiar with PowerShell at all, this seems like something which it would be good at doing. 如果你对PowerShell很熟悉,那么这似乎就是擅长做的事情。 Here's a way to do it in T-SQL if your SQL server happens to be MS SQL Server and you have rights to run xp_cmdshell. 如果您的SQL服务器恰好是MS SQL Server并且您有权运行xp_cmdshell,这是在T-SQL中执行此操作的方法。 I just wrote this out, so it doesn't have error checking, etc. 我刚写完了,所以它没有错误检查等。

DECLARE
    @image_files TABLE (file_path VARCHAR(MAX))

DECLARE
    @file_path VARCHAR(MAX),
    @cmd VARCHAR(MAX)

INSERT INTO @image_files (file_path)
EXEC xp_cmdshell 'dir *.jpg /b /s /x'
-- Change the extension if you use GIF, etc.

DECLARE file_cursor CURSOR FOR
    SELECT
        file_path
    FROM
        @image_files
    WHERE
        file_path NOT IN
        (
            SELECT file_path
            FROM
                My_Files
        )

OPEN file_cursor

FETCH NEXT FROM file_cursor INTO @file_path

WHILE (@@FETCH_STATUS = 0)
BEGIN
    SET @cmd = 'EXEC xp_cmdshell ''del ' + @file_path + ''''
    EXEC(@cmd)

    FETCH NEXT FROM file_cursor INTO @file_path
END

CLOSE file_cursor

DEALLOCATE file_cursor

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM