Как устранить эту ошибку «Отказано в доступе», возникающую при использовании 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

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

Изображение

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

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

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

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

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

--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.

Я также зашел в Facets > Surface Area Configuration и убедился, что xp_cmdshell включен/разрешен (true). Он также уже был помечен как true в разделе Facets > Server Security.


person Joshua Bryant    schedule 06.01.2017    source источник
comment
могут ли быть записи в #tmp, где eFileName - пустая строка? Я бы изменил это в While (Select Count(*) From #tmp where isnull(eFileName, '') ‹› '') › 0   -  person GuidoG    schedule 06.01.2017
comment
@GuidoG Я попытался заменить оператор while, как вы упомянули. К сожалению, я все еще получаю сообщение об ошибке.   -  person Joshua Bryant    schedule 06.01.2017
comment
Что возвращается, если запустить только EXEC xp_cmdshell 'dir /B C:\Users*****\Desktop\Test_Images'; ? Имейте в виду, что этот путь относится к серверу SQL, а не к клиенту, с которого вы его запускаете.   -  person Gareth Lyons    schedule 06.01.2017
comment
@GarethLyons, работающий только с EXEC xp_cmdshell 'dir /BC:\Users*****\Desktop\Test_Images, возвращает доступ отклонено и имеет значение Null.   -  person Joshua Bryant    schedule 06.01.2017
comment
@JoshuaBryant звучит очень похоже на разрешения на путь, в ответе данных назначения есть дополнительная информация об этом.   -  person Gareth Lyons    schedule 06.01.2017


Ответы (2)


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

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

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

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

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

person David Rushton    schedule 06.01.2017
comment
Папка существует и учетная запись имеет к ней полный доступ. Я обращаюсь к серверу через подключение к удаленному рабочему столу, имеет ли это какое-то значение? Кроме того, следующее, что вы бы использовали, чтобы включить его? 'EXEC sp_configure 'показать дополнительные параметры', 1 -- разрешить изменение дополнительных параметров. RECONFIGURE -- Чтобы обновить текущее настроенное значение для дополнительных параметров. EXEC sp_configure 'xp_cmdshell', 1 — для включения этой функции. RECONFIGURE -- Чтобы обновить текущее настроенное значение для этой функции.' - person Joshua Bryant; 06.01.2017
comment
Где находится папка? На вашем рабочем столе или на удаленном рабочем столе? - person David Rushton; 06.01.2017
comment
Начните с EXEC sp_configure 'show advanced options', 1; . Может быть уже включен. Если он не включен, прочтите это перед включением. xp_CmdShell представляет потенциальную угрозу безопасности. Если вы включите, я бы рекомендовал отключить после использования. - person David Rushton; 06.01.2017
comment
Я запустил ' EXEC sp_configure 'показать дополнительные параметры', 1; ' и получил это. Значит ли это, что он уже включен? Кроме того, папка находится в папке рабочего стола сервера (удаленный рабочий стол). - person Joshua Bryant; 06.01.2017
comment
Это просто означает, что вы включили просмотр дополнительных параметров. Вы можете проверить, что включено, запустив select * from sys.configurations или просто exec sp_configure — вы хотите, чтобы runvalue/value in use = 1 для xp_cmdshell. Также поддерживаю предложение приемника данных, чтобы снова отключить его, как только вы закончите, если это не требуется в другом месте. - person Gareth Lyons; 06.01.2017
comment
Спасибо @GarethLyons. Я запустил sp_configure, и он вернул это, что, как я полагаю, означает, что это включено. - person Joshua Bryant; 06.01.2017
comment
@JoshuaBryant да, это включено. В любом случае вы получите совсем другую ошибку, если она не будет включена. - person Gareth Lyons; 06.01.2017
comment
Спасибо @GarethLyons и destination-data за помощь! - person Joshua Bryant; 06.01.2017

Я понял!

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

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

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

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

1) Зайти в папку

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

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

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

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

6) Нажмите Добавить

7) Нажмите, чтобы выбрать принцип

8) Войдите в «Сервис» и проверьте имена

9) Выберите Сервис и нажмите ОК.

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

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

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

person Joshua Bryant    schedule 06.01.2017
comment
Безусловно, самая полезная для этой проклятой путаницы проблема с доступом запрещена. Ключ в том, чтобы предоставить Сервису доступ для чтения к скрипту Python, который я выполняю. - person Yu Shen; 24.04.2018