Pergunta

Existe uma maneira de chamar um procedimento ou função armazenada TSQL para um serviço da web?

Foi útil?

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.

  1. 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á bombar

  2. O 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.

  1. Aciona inserção e atualização em uma tabela
  2. 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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top