使用T-SQL从文件夹中删除多个文件而不使用游标

时间:2011-03-01 10:38:03

标签: sql sql-server sql-server-2005 tsql sql-server-2008

我正在写一个清理脚本。这个脚本将在周末运行并清理数据库。表与Eamils相关,附件路径存储在表中。在清理表格时,我还必须从文件夹中删除文件。

文件的路径如下。

\\xxx.xxx.xxx.xxx\EmailAttachments\Some Confirmation for xyz Children Centre_9FW4ZE1C57324B70EC79WZ15FT9FA19E.pdf

我可以删除多个文件,如下所示。

xp_cmdshell 'del c:\xyz.txt, abc.txt'

但是当我使用FOR XML PATH('')从表创建CSV时,字符串在结尾处被截断。可能有1000行要删除,所以我不想使用光标从文件夹中删除文件。

  1. 如何从文件夹中删除文件 不使用游标
  2. 我需要什么权限 使用来自sql server的t-sql删除文件的网络文件夹
  3. 修改 我使用过光标,看起来不错,没花太多时间。我面临的一个问题是

    • sql server将带空格的文件名视为两个文件,如下面的语句

      xp_cmdshell'del E:\ Standard Invite.doc'

    抛出错误

    Could Not Find E:\Standard
    Could Not Find C:\Windows\system32\Invite.doc
    NULL
    

    感谢。

4 个答案:

答案 0 :(得分:4)

就个人而言,我不会太担心在这里使用光标。游标只是“主要是邪恶的”;由于您的任务不是基于集合的操作,因此光标可能是最有效的解决方案。

答案 1 :(得分:3)

虽然您有一条评论声明使用游标需要“花费大量时间”,但在这种情况下,最大的开销是实际删除文件(而不是游标)。

注意:文件删除由操作系统完成,而不是由RDBMS完成。


由于删除是通过调用xp_cmdshell完成的,并且因为它是一个过程(不是函数等),所以你不能调用它并传入表的内容。

你可以做的是建立一个字符串,并执行它。但请注意,此字符串中最多限制为8000个字符。正如您已经说过的那样,您可能拥有数千个文件,但您认为它们不适合8000个字符。

这意味着无论如何你都需要一个循环。

DECLARE
  @command   VARCHAR(8000),
  @next_id   INT,
  @next_file VARCHAR(8000),
  @total_len INT

SELECT
  @command   = 'DEL ',
  @total_len = 4

SELECT TOP 1
  @next_id   = id,
  @next_file = file_name + ', '
FROM
  table_of_files_to_delete
ORDER BY
  id DESC

WHILE (@next_file IS NOT NULL)
BEGIN
  WHILE ((@total_len + LEN(@next_file)) <= 8000) AND (@next_file IS NOT NULL)
  BEGIN
    SELECT
      @command   = @command + @next_file,
      @total_len = @total_len + LEN(@next_file)

    SELECT
      @next_file = NULL

    SELECT TOP 1
      @next_id   = id,
      @next_file = file_name + ', '
    FROM
      table_of_files_to_delete
    WHERE
      id < @next_id
    ORDER BY
      id DESC
  END

  SET @command = SUBSTRING(@command, 1, @total_len - 2) -- remove the last ', '

  EXEC xp_cmdshell @command

  SELECT
    @command   = 'DEL ',
    @total_len = 4
END


不漂亮,是吗?

根据需要删除的内容,您可以使用外卡。例如:

EXEC xp_cmdshell 'DELETE C:\abc\def\*.txt'

答案 2 :(得分:1)

要删除名称中包含空格的文件,您需要使用"

包含文件名
xp_cmdshell 'del "E:\Standard Invite.doc"'

答案 3 :(得分:0)

DECLARE @deleteSql varchar(500)
   ,@myPath  varchar(500) = '\\DestinationFolder\'

SET @deleteSql = 'EXEC master..xp_cmdshell ''del '+@myPath +'*.csv'''
EXEC(@deleteSql)