Você pode chamar um webservice a partir do código TSQL?
-
09-06-2019 - |
Pergunta
Existe uma maneira de chamar um procedimento ou função armazenada TSQL para um serviço da web?
Solução
Sim, você pode criar assim
CREATE PROCEDURE CALLWEBSERVICE(@Para1 ,@Para2)
AS
BEGIN
Declare @Object as Int;
Declare @ResponseText as Varchar(8000);
Exec sp_OACreate 'MSXML2.XMLHTTP', @Object OUT;
Exec sp_OAMethod @Object, 'open', NULL, 'get', 'http://www.webservicex.com/stockquote.asmx/GetQuote?symbol=MSFT','false'
Exec sp_OAMethod @Object, 'send'
Exec sp_OAMethod @Object, 'responseText', @ResponseText OUTPUT
Select @ResponseText
Exec sp_OADestroy @Object
END
Outras dicas
Claro que você pode, mas esta é uma ideia terrível.
Como as chamadas de serviço da Web podem levar um tempo arbitrário e falhar aleatoriamente, dependendo de quantos jogos de contra-ataque estão sendo jogados na sua rede no momento, você não pode dizer quanto tempo isso levará.
No mínimo, você provavelmente levará meio segundo até o momento em que ele cria o XML, envia a solicitação HTTP ao servidor remoto, que então precisa analisar o XML e enviar uma resposta de volta.
Qualquer que seja a aplicação que
INSERT INTO BLAH
a consulta que causou o disparo do serviço da web terá que esperar até que ele termine.A menos que isso aconteça apenas em segundo plano, como uma tarefa agendada diariamente, o desempenho do seu aplicativo irá bombarO código que invoca o serviço da Web é executado dentro do SQL Server e consome seus recursos.Como vai demorar muito para esperar pela solicitação HTTP, você acabará consumindo muitos recursos, o que prejudicará novamente o desempenho do seu servidor.
Não no código T-SQL em si, mas com o SQL Server 2005 e superior, eles permitiram a capacidade de escrever procedimentos armazenados CLR, que são essencialmente funções no código .NET e depois expô-los como procedimentos armazenados para consumo.Você tem a maior parte do framework .NET ao seu alcance para isso, então posso ver o consumo de um serviço web possível através disso.
É um pouco demorado discutir em detalhes aqui, mas aqui está um link para um Artigo MSDN sobre o tema.
Eu não faria isso para tráfego intenso ou coisas de missão crítica. NO ENTANTO, se você NÃO precisa receber feedback de um serviço, então é realmente uma ótima coisa a fazer.
Aqui está um exemplo do que fiz.
- Aciona inserção e atualização em uma tabela
- Gatilho chamado Stored Proc que passa os dados JSON da transação para um Web Api Endpoint que então é inserido em um MongoDB na AWS.
Não faça XML antigo
JSON
EXEC sp_OACreate 'WinHttp.WinHttpRequest.5.1', @Object OUT;
EXEC sp_OAMethod @Object, 'Open', NULL, 'POST', 'http://server/api/method', 'false'
EXEC sp_OAMethod @Object, 'setRequestHeader', null, 'Content-Type', 'application/json'
DECLARE @len INT = len(@requestBody)
Exemplo completo:
Alter Procedure yoursprocname
@WavName varchar(50),
@Dnis char(4)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Object INT;
DECLARE @Status INT;
DECLARE @requestBody NVARCHAR(MAX) = '{
"WavName": "{WavName}",
"Dnis": "{Dnis}"
}'
SET @requestBody = REPLACE(@requestBody, '{WavName}', @WavName)
SET @requestBody = REPLACE(@requestBody, '{Dnis}', @Dnis)
EXEC sp_OACreate 'WinHttp.WinHttpRequest.5.1', @Object OUT;
EXEC sp_OAMethod @Object, 'Open', NULL, 'POST', 'http://server/api/method', 'false'
EXEC sp_OAMethod @Object, 'setRequestHeader', null, 'Content-Type', 'application/json'
DECLARE @len INT = len(@requestBody)
EXEC sp_OAMethod @Object, 'setRequestHeader', null, 'Content-Length', @len
EXEC sp_OAMethod @Object, 'send', null, @requestBody
EXEC sp_OAGetProperty @Object, 'Status', @Status OUT
EXEC sp_OADestroy @Object
Nas versões anteriores do SQL, você poderia usar um proc armazenado estendido ou xp_cmdshell para desembolsar e chamar um serviço da web.
Não que isso pareça uma arquitetura decente - mas às vezes você tem que fazer coisas malucas.
Você pode fazer isso com os objetos VB incorporados.
Primeiro você cria um objeto VB do tipo 'MSXML2.XMLHttp' e usa esse objeto para todas as suas consultas (se você recriá-lo toda vez, espere uma grande penalidade no desempenho).
Em seguida, você alimenta esse objeto, com alguns parâmetros, em um procedimento armazenado que invoca sp_OAMethod no objeto.
Desculpe pelo exemplo impreciso, mas uma rápida pesquisa no Google deve revelar como o método vb-script é feito.
--
Mas a versão CLR é muito...MUITO mais fácil.O problema de invocar webservices é que eles não conseguem acompanhar o mecanismo do banco de dados.Você receberá muitos erros onde ele simplesmente não consegue acompanhar.
E lembre-se, os SERVIÇOS da web exigem uma nova conexão a cada vez.A multiplicidade entra em jogo.Você não deseja abrir 5.000 conexões de soquete para atender uma chamada de função em uma tabela.Isso é maluco!
Nesse caso, você teria que criar uma função agregada personalizada e usar ISSO como argumento para passar para o seu serviço da web, que retornaria um conjunto de resultados... então você teria que agrupá-lo.É realmente uma maneira estranha de obter dados.
Se você estiver trabalhando com níveis de compatibilidade do sql 2000 e não puder fazer a integração do clr, consulte http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx
Tenho trabalhado para grandes empresas/globais ao redor do mundo, utilizando bancos de dados Oracle.Estamos consumindo serviços web o tempo todo através do banco de dados com procedimentos de armazenamento e sem problemas, mesmo aqueles com tráfego intenso.Todos eles para uso interno, ou seja, sem acesso à internet, apenas dentro da planta.Eu recomendaria usá-lo, mas tome muito cuidado ao projetá-lo