Невозможно получить доступ к подключенному NAS из хранимой процедуры - PullRequest
0 голосов
/ 31 января 2020

Любые идеи по устранению неисправностей или общие предложения очень приветствуются. У меня есть хранимая процедура, которая отображает местоположение файла NAS на мой локальный компьютер (используя XP_CMDSHELL) и выполняет итерации по базам данных в текущем экземпляре, выполняя резервное копирование для каждого. Этот SP отлично работает, когда выполняется вручную в SSMS и предоставляет параметры через интерфейс «Выполнить хранимую процедуру…».

Однако, когда я запускаю SP из программы C#, подключаюсь к экземпляру БД и выполняю объект SqlCommand, который содержит имя SP и дополнительные обязательные параметры для сопоставления NAS, SP не выполняется на каждой итерации попытки резервного копирования, указывая, что путь резервного копирования не может быть найден.

До сих пор я подтвердил, что правильная информация передается из C# в соединение SQL через объект команды. Информация об ошибке, возвращаемая с SQL на C#, указывает, что резервная копия SQL ищет правильный каталог. Также я подтвердил, что когда я передаю параметры диска для локального диска (например, «C:» с резервной папкой «Temp»), SP работает как положено.

Мне около 95 % уверен, что подключенный диск не виден SP, когда он выполняется из моей программы, и я почти уверен, что есть способ настроить выполнение SP, чтобы он видел этот подключенный диск; Я просто не знаю как. Я даже зашел так далеко, что установил ЗАДЕРЖКУ ОЖИДАНИЯ в 25 секунд после выполнения XP_CMDSHELL. Любая помощь приветствуется. Вот копия хранимой процедуры:

USE [nameofdb]
GO
/****** Object:  StoredProcedure to backup databases    Script Date: 1/31/2020 9:12:54 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[BackupDatabases]
    @networkPath [varchar](80), -- The Network path to be mapped for backup
    @backupFolder [varchar](60), -- The folder at the Network path to be backed up to
    @driveLetter [varchar](2) -- The Drive letter to be used for Network path mapping
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @dbName varchar(50) = '' -- The DB Name to be backed up
    DECLARE @path varchar(256) -- path of backup files
    DECLARE @fileName varchar(256) -- filename for backup
    DECLARE @fileDate varchar(20) -- used for file name
    DECLARE @netusePath varchar (100) -- used for full connect path
    SET @netusePath = concat('net use ', @driveLetter, ' ', @networkPath)
    EXEC XP_CMDSHELL @netusePath
    WAITFOR DELAY '00:00:25'
    SELECT @fileDate = CONVERT(varchar(20),GETDATE(),112)
    DECLARE db_cursor CURSOR FOR
        SELECT name FROM master.dbo.sysdatabases
        WHERE name NOT IN ('master','model','msdb','tempdb','ReportServer','ReportServerTempDB')
        OPEN db_cursor
            FETCH NEXT FROM db_cursor INTO @dbName
            WHILE @@FETCH_STATUS = 0 BEGIN
                SET @fileName = @driveLetter + '\' + @backupFolder + '\' + @dbName + '_' + @fileDate + '.BAK'
                BACKUP DATABASE @dbName TO DISK = @fileName
                FETCH NEXT FROM db_cursor INTO @dbName
            END
        CLOSE db_cursor
    DEALLOCATE db_cursor
    SET @netusePath = 'net use /delete ' + @driveLetter
    EXEC XP_CMDSHELL @netusePath
END

Ответы [ 2 ]

0 голосов
/ 03 февраля 2020

Большое спасибо @Larnu, который указал мне на направление использования путей UN C вместо букв дисков. При резервном копировании на путь UN C мой объект SqlCommand продолжал отсчитывать время, но исправление было следующим: во-первых, удалите строку WAITFOR DELAY '00: 00: 25 'из SPRO C (который был занят тайм-аут SqlCommand в любом случае). Во-вторых, я установил значение SqlCommand.CommandTimeout = 180. Между этими двумя изменениями программа и SPRO C теперь отлично работают вместе.

0 голосов
/ 31 января 2020

Я примерно на 95% уверен, что подключенный диск не виден SP

Вы можете создать процедуру тестирования (вызывается из приложения) и проверить, работает ли диск правильно сопоставлен, и если папка резервной копии существует (перехватите вывод dir)

..............

SET @netusePath = concat('net use ', @driveLetter, ' ', @networkPath)
EXEC XP_CMDSHELL @netusePath
WAITFOR DELAY '00:00:25'

--check if the share is mapped
declare @checkdrive varchar(50) = 'dir ' + @driveLetter;
exec xp_cmdshell @checkdrive;

--check if the backup folder exists
declare @checkfolder varchar(50) = 'dir ' + @driveLetter + '\' + @backupFolder ;
exec xp_cmdshell @checkfolder;

 .....................
...