Clique no banner para conhecer e adquirir o meu treinamento de Bancos de Dados no Azure

SQL Server e Power BI: Como carregar dados de Stored Procedure no SQL Server com DirectQuery

Visualizações: 6.571 views
Tempo de Leitura: 7 minutos

IntroduĂ§Ă£o

Fala pessoal!

Nesse post eu gostaria de compartilhar com vocĂªs uma situaĂ§Ă£o que aconteceu comigo durante uma consultoria a um cliente, onde ele tinha uma necessidade de ter um relatĂ³rio do Power BI conectado Ă  uma base de dados SQL Server, mas a fonte de dados era uma Stored Procedure que fazia vĂ¡rias transformações de dados internamente e retornava um conjunto de dados.

O problema Ă© que esse cliente queria que a atualizaĂ§Ă£o dos dados fosse em tempo real, ou seja, abriu o relatĂ³rio, aplicou um filtro ou fez uma interaĂ§Ă£o com o grĂ¡fico, os dados teriam que ser atualizados atravĂ©s da execuĂ§Ă£o dessa Stored Procedure. E acontece que o Power BI NĂƒO tem suporte Ă  isso đŸ™‚

Caso vocĂª queira aprender mais sobre o DirectQuery do Power BI, veja esse conteĂºdo aqui.

Esse Ă© o cĂ³digo da Stored Procedure que eu gostaria de executar como DirectQuery no Power BI:

Resultado esperado da execuĂ§Ă£o:

Simulando o problema

Clique aqui para visualizar este conteĂºdo
O primeiro passo para tentar executar uma procedure com DirectQuery Ă© selecionar esse tipo de armazenamento, digitar o nome do servidor e clicar no botĂ£o OK para carregar a lista de objetos:

Na listagem dos objetos, podemos observar que ele sĂ³ lista tabelas, views e funções:

Vou voltar para a tela de conexĂ£o e tentar inserir o comando de execuĂ§Ă£o manualmente na tela de instruĂ§Ă£o SQL:

Mas ao tentar fazer isso, Ă© retornada uma mensagem de erro:

Vamos tentar de novo, sem colocar a instruĂ§Ă£o EXEC:

Opa! Parece que carregou!

Parecia que ia funcionar, mas ao tentar carregar os dados..

O PowerQuery atĂ© mostra os dados do banco, mas nĂ£o me deixa carregar para o modelo, mostrando a mensagem do print anterior.

SoluĂ§Ă£o #1 – OpenRowSet

Clique aqui para visualizar este conteĂºdo
A primeira “soluĂ§Ă£o” que vou apresentar pra vocĂªs, Ă© a utilizaĂ§Ă£o do OpenRowSet para executar a procedure no servidor local e retornar os dados. Como essa acaba sendo uma instruĂ§Ă£o SELECT, o Power BI deve aceitar a execuĂ§Ă£o:

O primeiro ponto a ser considerado, Ă© essa mensagem de erro abaixo:

Msg 15281, Level 16, State 1, Line 43
SQL Server blocked access to STATEMENT ‘OpenRowset/OpenDatasource’ of component ‘Ad Hoc Distributed Queries’ because this component is turned off as part of the security configuration for this server. A system administrator can enable the use of ‘Ad Hoc Distributed Queries’ by using sp_configure. For more information about enabling ‘Ad Hoc Distributed Queries’, search for ‘Ad Hoc Distributed Queries’ in SQL Server Books Online.

Essa mensagem nada mais representa que o recurso de OpenRowset/OpenDatasource estĂ¡ desativado na instĂ¢ncia (por padrĂ£o, essa configuraĂ§Ă£o vem desativada devido Ă  motivos de segurança). Para utilizar o Openrowset, vocĂª precisarĂ¡ habilitar esse recurso, e o seu DBA provavelmente nĂ£o irĂ¡ gostar isso:

Uma vez habilitado, agora basta executar o nosso comando de SELECT. E nos deparamos com a 2ª mensagem de erro:

Msg 11526, Level 16, State 1, Procedure sys.sp_describe_first_result_set, Line 1 [Batch Start Line 53] The metadata could not be determined because statement ‘INSERT INTO #Tabelas_Internas
VALUES(965578478, ‘Tabela de Confirmados’), (1013578649, ‘Tabela’ in procedure ‘stpPBI_DirectQuery_Procedure’ uses a temp table.

Agora o SQL Server estĂ¡ reclamando das tabelas temporĂ¡rias utilizadas na Stored Procedure. Vamos fazer algumas alterações na procedure e substituir as tabelas temporĂ¡rias (#tabela) por variĂ¡veis do tipo tabela (@tabela):

E vamos tentar novamente. Outra mensagem de erro:

Msg 7357, Level 16, State 1, Line 54
Cannot process the object “EXEC eventos.dbo.stpPBI_DirectQuery_Procedure”. The OLE DB provider “SQLNCLI11” for linked server “(null)” indicates that either the object has no columns or the current user does not have permissions on that object.

Para resolver esse problema, vamos incluir a instruĂ§Ă£o “SET NOCOUNT ON” no começo da Stored Procedure, para que o comando de OPENROWSET consiga identificar corretamente os dados retornados e nĂ£o sofra interferĂªncias com o retorno da quantidade de linhas retornadas:

Com essa alteraĂ§Ă£o, o nosso comando de SELECT foi executado corretamente:

Vamos voltar para o Power BI, repetir todo o processo e agora podemos carregar os dados normalmente pra dentro do Power BI:

E estĂ¡ lĂ¡! Estamos consumindo uma Stored Procedure usando DirectQuery no Power BI!

SoluĂ§Ă£o #2 – Utilizando Table-Valued Function

Clique aqui para visualizar este conteĂºdo
A segunda forma de conseguir consultar objetos complexos utilizando DirectQuery no Power BI, Ă© substituindo a Stored Procedure por uma Table-Valued Function, que acaba sendo uma forma bem mais elegante e correta de realizar essa consulta do que a forma anterior.

Segue o cĂ³digo da funĂ§Ă£o, que realiza exatamente a mesma coisa da Stored Procedure anterior:

ApĂ³s a criaĂ§Ă£o da funĂ§Ă£o, selecione a opĂ§Ă£o “Obter Dados” > “SQL Server” e escreva o comando de SELECT para ler os dados da funĂ§Ă£o:

ApĂ³s clicar no botĂ£o de “OK”, seus dados estarĂ£o sendo carregados normalmente:

Basta clicar no jĂ¡ conhecido botĂ£o “Fechar e Aplicar” e a nossa tarefa estĂ¡ feita.

Limitações

O uso de Stored Procedures ou funções para conectar a dados com DirectQuery tem algumas limitações as quais posso destacar:

  • NĂ£o Ă© possĂ­vel passar parĂ¢metros dinĂ¢micos para Stored Procedure ou Table-valued function dinamicamente
  • Ao utilizar um slicer, por exemplo, os dados sĂ£o executados no banco de dados para depois filtrar os dados retornados utilizando os slicers, portanto, isso talvez gere problemas de performance em tabelas muito grandes
  • Diferente do relatĂ³rio paginado, que recalcula todo o conjunto de dados apĂ³s interações com os usuĂ¡rios, o Power BI nĂ£o atualiza os dados na fonte a cada filtro aplicado ou interaĂ§Ă£o no DirectQuery
  • As 2 soluções vĂ£o apresentar problemas de performance em grandes volumes de dados
  • As 2 tĂ©cnicas apresentadas exigem um certo conhecimento em T-SQL e sĂ³ funciona no SQL Server. Talvez isso seja um pouco complexo de trabalhar para um usuĂ¡rio de negĂ³cio que nĂ£o Ă© de TI
  • O DirectQuery por si sĂ³, jĂ¡ possui algumas limitações que pode vocĂª entrar acessando esse link aqui

É isso aí, pessoal!
Espero que tenham gostado dessa dica, que isso seja Ăºtil pra vocĂª em alguma necessidade especĂ­fica e atĂ© a prĂ³xima!