Eu tenho um procedimento armazenado complexo que consulta pastas de rede específicas, coleta os nomes dos arquivos de backup do SQL Server que encontra lá e processa cada arquivo para obter detalhes. Se eu executar o procedimento do SSMS versão 18.4, ele dará os resultados errados. Mas se eu executá-lo no SSMS versão 17.9, o procedimento me fornecerá os dados que espero ver.
Eu posso recriar o problema com um exemplo mais simples:
CREATE OR ALTER PROCEDURE TestOutput (
@HostName nvarchar(255),
@DbName nvarchar(255)
)
AS
BEGIN
Declare @cmd nvarchar(500);
Declare @basePath nvarchar(500) = '\\Server1\DB_Backups\SQL\' + @HostName + '\' + @DbName + '\';
Create table #FullFileList (backupPath nvarchar(255), backupFile NVARCHAR(255)) ;
SET @cmd = 'DIR /b "' + @basePath + 'Full\"';
INSERT INTO #FullFileList (backupFile) EXEC master.sys.xp_cmdshell @cmd;
update #FullFileList set backupPath = @basePath + 'Full\';
SET @cmd = 'DIR /b "' + @basePath + 'Diff\"';
INSERT INTO #FullFileList (backupFile) EXEC master.sys.xp_cmdshell @cmd
update #FullFileList set backupPath = @basePath + 'Diff\' where backupPath is null;
SET @cmd = 'DIR /b "' + @basePath + 'Log\"'
INSERT INTO #FullFileList (backupFile) EXEC master.sys.xp_cmdshell @cmd;
update #FullFileList set backupPath = @basePath + 'Log\' where backupPath is null;
select * from #FullFileList;
select count(*) from #FullFileList;
END
GO
Se eu executar este procedimento do SSMS versão 17.9 em uma pasta pai (caminho base) que contém 1.950 arquivos nas três subpastas, a saída será 1.953 linhas (três linhas com nomes de arquivo nulos estão na lista, uma para cada pasta). E a saída da contagem é 1.953.
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Full\ Host_Name_DB_Name_FULL_20191230_040407.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Full\ Host_Name_DB_Name_FULL_20200106_040407.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Full\ Host_Name_DB_Name_FULL_20200113_040407.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Full\ NULL
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200103_050507.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200104_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200105_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200107_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200108_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200109_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200110_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200111_050507.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200112_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200114_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200115_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ Host_Name_DB_Name_DIFF_20200116_050506.bak
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Diff\ NULL
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ Host_Name_DB_Name_LOG_20200112_104703.trn
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ Host_Name_DB_Name_LOG_20200112_105003.trn
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ Host_Name_DB_Name_LOG_20200112_105302.trn
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ Host_Name_DB_Name_LOG_20200112_105602.trn
[... Snip ...]
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ Host_Name_DB_Name_LOG_20200116_144402.trn
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ Host_Name_DB_Name_LOG_20200116_144703.trn
\\Server1\DB_Backups\SQL\Host_Name\DB_Name\Log\ NULL
1953
No entanto, se eu executar esse mesmo código no SSMS versão 18.4, o procedimento produzirá 9 linhas de saída. Ele também me diz que a contagem é de 22 linhas, o que também é falso: a saída acabou de ser fornecida; havia apenas nove linhas retornadas.
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Full\ WTR320MSDNCM_DBMonitoring_FULL_20191230_040407.bak
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Full\ WTR320MSDNCM_DBMonitoring_FULL_20200106_040407.bak
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Full\ WTR320MSDNCM_DBMonitoring_FULL_20200113_040407.bak
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Full\ NULL
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Log\ WTR320MSDNCM_DBMonitoring_LOG_20200112_104703.trn
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Log\ WTR320MSDNCM_DBMonitoring_LOG_20200112_105003.trn
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Log\ WTR320MSDNCM_DBMonitoring_LOG_20200112_105302.trn
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Log\ WTR320MSDNCM_DBMonitoring_LOG_20200112_105602.trn
\\wtrnas\DB_Backups\SQL\wtr320msdncm\DBMonitoring\Log\ WTR320MSDNCM_DBMonitoring_LOG_20200112_105902.trn
22
(são todas as linhas retornadas quando executadas a partir de 18.4)
Novamente, exatamente o mesmo código, mesmo mecanismo de banco de dados no back-end (Microsoft SQL Server 2017 CU18 Enterprise Edition no Windows Server 2012 R2 Standard), apontado para a mesma estrutura de pastas no Server1. A única diferença é a versão do SSMS que executa o comando create procedure.
Observe que o SQLCMD também fornece a saída correta.
Eu tentei desinstalar e reinstalar o SSMS 18.4. Eu também tentei mudar isso para uma tabela não temporária. A versão do SSMS 18.4 cria 9 linhas de dados, não 1953 linhas, que posso visualizar de fora do procedimento. Eu tentei mudar a ordem em que as pastas são processadas; isso não altera o resultado.
O SQL Server tem todas as permissões necessárias para navegar nas três pastas em questão; ele realmente escreveu esses arquivos.
Mas por que a versão do SSMS é um fator? Isso tudo deve ser executado a partir do servidor, que não está mudando aqui. Como posso fazer este procedimento funcionar corretamente em 18.4, ou por que NÃO está funcionando corretamente?
Eu vejo seu comentário que
Você pode conseguir o mesmo configurando as opções de menu no SSMS: