Member 10379103 Ответов: 2

Использование SQL для копирования и удаления файлов в каталогах


Вот с чем мне дали поработать и что работает уже несколько недель:

declare @cmdstring varchar(1000)
DECLARE @PATH VARCHAR(256)
DECLARE @FILENAME VARCHAR(500)




SET @PATH =   'dir \\myservername\c$\myFolderName\SubFolderName\*Everything*.xls /A-D  /B  /O-D'

set @cmdstring = 'DEL "\\myservername\c$\myFolderName\SubFolderName\TheOutFolder\FinalFile.csv'
exec master..xp_cmdshell @cmdstring,no_output
PRINT 'The file has been deleted.'

set @cmdstring = 'copy "\\myservername\c$\myFolderName\SubFolderName\' + @filename  + '"  "C:\myFolderName\SubFolderName\' + @filename + ' "'
exec master..xp_cmdshell @cmdstring,no_output
Print 'The file has been copied.'


Вышеизложенное выполнялось каждый день как запланированное задание. Затем, вчера, процесс запустился, но файл не был скопирован. Я проверил файл журнала, связанный с этим шагом запланированного задания, и команды печати были в файле журнала, но ничего не было скопировано или удалено. Задание не регистрировало никаких ошибок. Сервер не регистрировал никаких ошибок.

Ниже приведен файл журнала:

Job 'Job_Name' : Step 1, 'Import and Process the files' : Began Executing 2016-12-12 00:30:00

dir \\myservername\c$\myFolderName\SubFolderName\*Everything*.xls /A-D  /B  /O-D [SQLSTATE 01000]
The File has been deleted. [SQLSTATE 01000]
File copied from myservername to myfoldername [SQLSTATE 01000]
output                                                                                                                                                                                                                                                         
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(null)
Copy to myservername Processed folder done [SQLSTATE 01000]
Server copy deleted [SQLSTATE 01000]
output                                                                                                                                                                                                                                                         
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(null)
output                                                                                                                                                                                                                                                         
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(null)
output                                                                                                                                                                                                                                                         
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
(null)
Return Value
------------
0

(1 rows(s) affected)


Когда я попытался вручную запустить DEL (как я уже делал в прошлом), мой оператор "print" напечатал, но файл не удалялся. Я проверил у своего системного администратора, и там были некоторые процессы отката, блокирующие и блокирующие некоторые процессы базы данных.

Затем все было удалено и скопировано, как обычно, через два часа.

Мои вопросы таковы:

1. Почему моя команда failed copy не зарегистрировала сбой задания (шаг настроен на регистрацию сбоя и отправку электронного письма).
2. Почему бы мне не иметь возможности удалить файл из моего каталога с помощью SQL (как я уже делал раньше, а затем таинственным образом иметь возможность удалить свой файл и иметь свою работу успешно скопировать и удалить мой файл.

Одно отличие, которое я замечаю, заключается в том, что когда я вызываю хранимую процедуру через запланированное задание, я делаю это следующим образом: EXECUTE myStoredProcedureName.

Это задание вызывает хранимую процедуру следующим образом:
USE [MyDatabaseName]
GO

DECLARE	@return_value int

EXEC	@return_value = [dbo].[myStoredProcedure]

SELECT	'Return Value' = @return_value

GO


Что я уже пробовал:

Я искал веб-сайт MSDN и блоги, другие доски объявлений.

Richard Deeming

Это то, что SQL никогда не собирался делать. Если вы запускаете его как задание агента SQL, вам лучше создать пакетный файл или сценарий Powershell и выполнить его как Операционная Система (CmdExec)[^] шаг.

Member 10379103

Ричард,
Спасибо за предложение. Я также не привык полагаться на SQL для таких действий. Это был путь, который уже был проложен, когда я добрался сюда.
Я продолжу исследовать ваше предложение. Есть еще одно предложение, опубликованное на мой вопрос, которое кажется очень похожим. Спасибо!

2 Ответов

Рейтинг:
2

Wendelius

Я не могу сказать, почему копирование или удаление не удалось, но я бы посоветовал не использовать xp_cmdshell для прямого запуска команд ОС.

Самая важная причина заключается в том, что, хотя вы можете выполнять команды, у вас нет надлежащих инструментов для регистрации или обработки ошибок.

Если вам действительно нужно использовать xp_cmdshell, я бы предложил, по крайней мере, запустить сценарии powershell и добавить в сценарий обработку ошибок и ведение журнала. На мой взгляд, лучшим способом было бы создать процедуру CLR, которую вы могли бы вызвать из базы данных. Внутри этой процедуры вы можете использовать (почти) все возможности .Net, предлагаемые в качестве фреймворка.

Если вам интересно, взгляните, например, на Запись в файл из базы данных[^]. Этот пример не совсем то, что вам нужно, но процедура имеет такие же файловые операции, как и в ваших командах.


Рейтинг:
2

Er Sagar Mahajan Pune

--For copy 

Exec xp_cmdshell 'copy "D:\OldLocationfolder\abc.txt" "E:\NewLocationfolder\"'

-- copy abc.txt file from D drive to E drive

--================================================

--For delete 

Exec xp_cmdshell 'del "D:\myfolder\abc.txt"' 

-- delete abc.txt file from D drive.


CHill60

Оп уже знает, как это сделать - смотрите подробности в их посте. Вопрос состоял в том, почему он вдруг перестал отказывать, и этот код даже не пытается ответить на этот вопрос.