Estou tentando executar sp_AskBrent
do PowerShell usando Invoke-SQLCmd
e capturar sua saída em uma variável:
$query = "EXEC SAIDBA.monitoring.sp_AskBrent @Seconds=10;"
$check = Invoke-Sqlcmd -ServerInstance $ServerInstance -Query $query
-ErrorAction Stop -ConnectionTimeout 3
Ao executar com ExpertMode = 0 , não há problema.
Mas ao executar com ExpertMode = 1 , notamos três coisas:
- Ele gera todos os dados para o shell
$check
é nuloTermina com o seguinte erro:
Invoke-Sqlcmd : nomes de coluna duplicados não são permitidos no SQL PowerShell. Para repetir uma coluna, use um alias de coluna para a coluna duplicada no formato Column_Name AS New_Name.
Na linha:1 caractere:18- $check = Invoke-Sqlcmd -ServerInstance $ServerInstance -Query $query -Er ...
- CategoryInfo: SyntaxError: (:) [Invoke-Sqlcmd], SqlPowerShellSqlExecutionException
- FullyQualifiedErrorId: DuplicateColumnNameErrorMessage, Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
Acho que há uma solução alternativa para fornecer parâmetros para sp_AskBrent
armazenar os dados do ExpertMode em tabelas e selecionar essas tabelas posteriormente, mas quero ter certeza de que não há como recuperar tudo de uma vez no PowerShell.
Brent aqui. Correto, @ExpertMode = 1 ativa vários conjuntos de resultados - diagnósticos, estatísticas de espera, estatísticas de arquivo e contadores de perfmon.
Se você deseja apenas um conjunto de resultados, não ative @ExpertMode.
Se você deseja vários conjuntos de resultados, mas seu aplicativo (neste caso, PoSH) não pode consumi-los, você precisará registrá-los nas tabelas. É aí que entram esses parâmetros:
Se você deseja que funcione de maneira diferente, descreva o que precisa e verei se consigo encontrar uma maneira de obtê-lo. Espero que ajude!
De um comentário:
OK legal. Apenas algumas coisas a serem lembradas - as tabelas não se limpam sozinhas e podem ficar grandes se você usar o
@SkipChecksQueries = 0
parâmetro, por exemplo. Osp_AskBrent®
licenciamento também proíbe a distribuição, portanto, certifique-se de não empacotar o script ou instalá-lo em servidores que não são seus. Caso contrário, vá em frente! Se houver algo que eu possa fazer para ajudar a tornar isso mais fácil, grite.Há um campo de data em todas as tabelas de saída para ajudá-lo a manter as tabelas de histórico.
Para não descartar a resposta de Brent (embora às vezes ele dê algumas boas em seu treinamento) ...
No PowerShell, você pode executar consultas que retornam vários conjuntos de dados, mas não pode fazer isso
Invoke-Sqlcmd
, pois não foi criado para isso atualmente.Você teria duas opções de fazer isso com o código nativo .NET (por exemplo
System.Data.SqlClient
) ou usando o confiávelSMO
. Costumo escolherSMO
simplesmente no caso de querer incluir propriedades do servidor ou qualquer outra coisa queSMO
tenha acesso.No contexto de
sp_AskBrent
, fui em frente e passei alguns minutos apenas construindo a saída em um relatório HTML. Os principais pontos de interesse neste script é que, para lidar com vários conjuntos de dados, você executará sua consulta com oExecuteWithResults
método disponível nos seguintes namespaces:Microsoft.SqlServer.Management.Smo.Server
Microsoft.SqlServer.Management.Smo.Database
Você pode ver um exemplo de uso do
database
namespace no MSDN aqui . No meu script, estou usando oServer
namespace. Funcionará de qualquer maneira, mas se você revisar o artigo do MSDNExecuteWithResults
, retornará umDataSet
objeto e esse objeto conterá um arquivoDataTable
. O número deDataTables
é baseado no número de conjuntos de dados retornados pelo seu código. No caso do procedimento de Brent você receberá de volta 5DataTables
. Você pode verificar isso no código abaixo adicionando$results.Count
, logo antes doforeach
loop.Agora, uma outra observação neste script é que escolhi enviar para HTML. Você pode escolher outro formato, se desejar, mas enviar tudo para o console não é legível. Também observarei que adicionei informações de ajuda para que você possa usar
Get-Help
no script se precisar ver detalhes sobre os parâmetros ou lembrar-se de como chamá-lo.Usei um pequeno trecho de código de Pinal Dave apenas para gerar algum uso de CPU em minha instância local para este exemplo. (Caso contrário, o procedimento não retornou muitas informações).
Roteiro