2017-01-06 5 views
1

Это вся моя рутина:Как устранить эту ошибку «Отказано в доступе», которая возникает при использовании xp_cmdshell в Microsoft SQL?

Declare @AttFileType as char(5), @HQCo as int, @FormName as Varchar(15),  @KeyID as VarChar(10), @UniqueID as uniqueidentifier, @FilePath as Varchar(100), @StringCommand as Varchar(200) 
Declare @AttID as int 
DECLARE @cmd as VARCHAR(500) 
DECLARE @cmd2 as VARCHAR(500) 


CREATE TABLE #tmp(eFileName VARCHAR(100)); 
INSERT INTO #tmp 
EXEC xp_cmdshell 'dir /B C:\Users\*****\Desktop\Test_Images'; 

Declare @FileName varchar(100) 

Set @UniqueID = NewID() 

While (Select Count(*) From #tmp where eFileName is not null) > 0 
Begin 

Select Top 1 @FileName = eFileName From #tmp 

Set @FilePath = 'C:\Users\*****\Desktop\Test_Images\' + @FileName 

Set @AttID = (Select TOP 1 AttachmentID FROM dbo.bHQAF ORDER BY AttachmentID DESC) + 1 
Set @AttFileType = '.jpg' 


Insert Into dbo.bHQAF (AttachmentID, AttachmentFileType) 
Select @AttID, @AttFileType 


SET @cmd = ' 
Declare @AttID2 as int, @AttFileType2 as char(5), @FilePath2 as Varchar(100) 

Set @AttFileType2 = ''.jpg'' 
Set @AttID2 = (Select TOP 1 AttachmentID FROM dbo.bHQAF ORDER BY AttachmentID DESC) 


Update dbo.bHQAF 
Set AttachmentData = (SELECT * From OPENROWSET (Bulk ''' + @FilePath + ''', Single_Blob) rs) 
Where AttachmentID = @AttID2 and AttachmentFileType = @AttFileType2' 

Exec (@cmd) 

Set @HQCo = 101 
Set @FormName = 'HRCompAssets' 
Set @KeyID = 'KeyID=2' 


Insert Into dbo.bHQAT (HQCo, AttachmentID, FormName, KeyField, UniqueAttchID) 
Select @HQCo, @AttID, @FormName, @KeyID, @UniqueID 

Insert Into dbo.bHQAI (AttachmentID, HRCo) 
Select @AttID, @HQCo 

Update dbo.bHQAT 
Set Description = 'TEST3', AddDate = GETDATE(), AddedBy = '****', DocAttchYN = 'N', DocName = 'Database', OrigFileName = @FileName, TableName = 'HRCA' 
Where AttachmentID = @AttID and HQCo = @HQCo 

Insert Into dbo.bHQAI (AttachmentID, HRCo) 
Select @AttID, 101 

Update dbo.bHRCA 
Set UniqueAttchID = @UniqueID 
Where HRCo = 101 and Asset = '00001' 

Delete from #tmp Where eFileName = @FileName 

End 

Я проверил, что код работает, для загрузки одного изображения на сервер, без этого бита здесь:

-- Declarations here 

CREATE TABLE #tmp(eFileName VARCHAR(100)); 
INSERT INTO #tmp 
EXEC xp_cmdshell 'dir /B C:\Users\*****\Desktop\Test_Images'; 

While (Select Count(*) From #tmp where eFileName is not null) > 0 
Begin 

Select Top 1 @FileName = eFileName From #tmp 


-- Rest of code here 


Delete from #tmp Where eFileName = @FileName 

End 

Но как только время цикла и Добавлены инструкции xp_cmdshell, имя файла возвращается как «Доступ запрещен».

Image

Любая помощь будет оценен по достоинству!

Я не специалист по SQL, но меня попросили загрузить около 1000 файлов PDF и JPEG в базу данных, и сценарий, казалось, был наиболее логичным подходом.

Когда все сказано и сделано, я хотел бы, чтобы сценарий захватил каждое изображение из папки и загрузил его в базу данных.

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

Edit: Я также попытался добавить следующее в начале кода, которые не решить вопрос:

--Allow for SQL to use cmd shell 
EXEC sp_configure 'show advanced options', 1 -- To allow advanced options to be changed. 
RECONFIGURE -- To update the currently configured value for advanced options. 
EXEC sp_configure 'xp_cmdshell', 1 -- To enable the feature. 
RECONFIGURE -- To update the currently configured value for this feature. 

Я также пошел в Грани> Настройка контактной зоны и удостоверились xp_cmdshell включен/allowed (true). Это также было отмечено в разделе «Границы»> «Безопасность сервера».

+0

Может ли быть запись в #tmp, где eFileName - пустая строка? Я бы изменил это в «While (Select Count (*) from #tmp, где isnull (eFileName, '') <> '')> 0" – GuidoG

+0

@GuidoG Я попытался заменить оператор while, как вы уже упоминали. К сожалению, я все еще получаю ошибку. –

+0

Что возвращается, если вы запускаете только EXEC xp_cmdshell 'dir/B C: \ Users \ ***** \ Desktop \ Test_Images'; ? Имейте в виду, что этот путь относится к SQL-серверу, а не к клиенту, с которого вы его запускаете. –

ответ

4

Здесь есть несколько возможных проблем.

xp_cmdShell работает на сервере. Если на этой машине нет папки с именем C:\Users\*****\Desktop\Test_Images, она не будет работать.

xp_CmdShell работает с использованием service account. Если у этой учетной записи нет разрешений в целевой папке, она не удастся.

xp_CmdShell должен быть включен. От MSDN.

Опция xp_cmdshell является параметром конфигурации сервера SQL-сервер, который позволяет системным администраторам контролировать xp_cmdshell расширен ли хранимая процедура может быть выполнена в системе. По умолчанию параметр xp_cmdshell отключен при новых установках и может быть включен с помощью управления на основе политик или путем запуска хранимой процедуры sp_configure .

+0

Папка существует, и учетная запись имеет полный доступ к ней. Я обращаюсь к серверу через соединение с удаленным рабочим столом, не имеет значения? Кроме того, является ли следующее, что вы хотели бы включить? 'EXEC sp_configure' показать дополнительные параметры ', 1 - Чтобы разрешить дополнительные параметры. RECONFIGURE - Чтобы обновить текущее настроенное значение для расширенных параметров. EXEC sp_configure 'xp_cmdshell', 1 - включение функции. RECONFIGURE - Чтобы обновить текущее настроенное значение для этой функции. ' –

+0

Где находится папка? На вашем рабочем столе или удаленном рабочем столе? –

+0

Начните с простого 'EXEC sp_configure 'показать дополнительные параметры', 1; '. Может быть уже включен. Если он не включен, прочитайте [this] (https://msdn.microsoft.com/en-us/library/ms175046.aspx#Permissions) перед включением. xp_CmdShell - потенциальный риск для безопасности. Если вы включите, я рекомендую отключить его после использования. –

0

Я понял!

Спасибо @ destination-data & @ GarethLyons за помощь!

Вы, ребята, были правы, возникла проблема с разрешениями на папку, которые я не понимал, что мне нужно будет войти в папку и вручную обновить разрешения, чтобы включить «Сервис». Как только я это сделал, все сработало отлично!

Спасибо вам снова, извините за путаницу.

Для любого другого, кто с этой проблемой в будущем, выполните следующие действия первой:

1) Заходим в папку

2) Нажмите правой кнопкой мыши

3) Выберите свойства

4) Выберите вкладку «Безопасность»

5) Нажмите «Дополнительно»

6) Нажмите кнопку Добавить

7) Нажмите кнопку выбора принципа

8) Введите "Сервис" и Проверить имена

9) Выберите службу и нажмите OK

10) Выберите соответствующие разрешения в разделе «Основные разрешения»

11) Выберите «применяются только эти разрешения на объект в контейнере»

12) Примените изменения и попробуйте запустить xp_cmdshell снова