我正在写一个清理脚本。这个脚本将在周末运行并清理数据库。表与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行要删除,所以我不想使用光标从文件夹中删除文件。
修改 我使用过光标,看起来不错,没花太多时间。我面临的一个问题是
sql server将带空格的文件名视为两个文件,如下面的语句
xp_cmdshell'del E:\ Standard Invite.doc'
抛出错误
Could Not Find E:\Standard
Could Not Find C:\Windows\system32\Invite.doc
NULL
感谢。
答案 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)