Domanda

Esiste un modo per chiamare da una procedura o funzione memorizzata TSQL a un servizio web?

È stato utile?

Soluzione

Sì, puoi creare in questo modo

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

Altri suggerimenti

Certo tu Potere, ma questa è un'idea terribile.

Poiché le chiamate al servizio Web possono richiedere quantità di tempo arbitrarie e fallire in modo casuale, a seconda di quante partite di contrattacco vengono giocate sulla rete in quel momento, non è possibile sapere quanto tempo richiederà.

Come minimo stai guardando probabilmente mezzo secondo nel momento in cui crea l'XML, invia la richiesta HTTP al server remoto, che quindi deve analizzare l'XML e inviare una risposta.

  1. Qualunque sia l'applicazione che ha eseguito il INSERT INTO BLAH La query che ha causato l'attivazione del servizio Web dovrà attendere il suo completamento.A meno che non si tratti di qualcosa che accade solo in background, come un'attività pianificata quotidianamente, le prestazioni della tua app saranno incredibili

  2. Il codice che richiama il servizio Web viene eseguito all'interno del server SQL e utilizza le sue risorse.Poiché ci vorrà molto tempo per attendere la richiesta HTTP, finirai per utilizzare molte risorse, il che danneggerà nuovamente le prestazioni del tuo server.

Non nel codice T-SQL in sé, ma con SQL Server 2005 e versioni successive, è stata abilitata la possibilità di scrivere procedure memorizzate CLR, che sono essenzialmente funzioni nel codice .NET, per poi esporle come procedure memorizzate per l'utilizzo.Hai la maggior parte del framework .NET a portata di mano per questo, quindi posso vedere il consumo di un servizio Web possibile attraverso questo.

È un po' lungo discutere in dettaglio qui, ma ecco un collegamento a un Articolo MSDN sull'argomento.

Non lo farei per traffico intenso o cose cruciali, TUTTAVIA, se NON hai bisogno di ricevere feedback da un servizio, allora è davvero un'ottima cosa da fare.

Ecco un esempio di ciò che ho fatto.

  1. Attiva l'inserimento e l'aggiornamento su una tabella
  2. Trigger chiamato Stored Proc che passa i dati JSON della transazione a un endpoint Web Api che quindi inserisce in un MongoDB in AWS.

Non eseguire il vecchio XML

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) 

Esempio 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

Nelle versioni precedenti di SQL, era possibile utilizzare un proc memorizzato esteso o xp_cmdshell per eseguire il shelling e chiamare un servizio web.

Non che nessuna di queste sembri un'architettura decente, ma a volte devi fare cose pazze.

Puoi farlo con gli oggetti VB incorporati.

Per prima cosa crei un oggetto VB di tipo "MSXML2.XMLHttp" e usi questo oggetto per tutte le tue query (se lo ricrei ogni volta aspettati una pesante penalità in termini di prestazioni).

Quindi inserisci l'oggetto e alcuni parametri in una procedura memorizzata che richiama sp_OAMethod sull'oggetto.

Ci scusiamo per l'esempio impreciso, ma una rapida ricerca su Google dovrebbe rivelare come viene eseguito il metodo vb-script.

--

Ma la versione CLR è molto... MOLTO più semplice.Il problema con l'invocazione dei servizi web è che non riescono a tenere il passo con il motore DB.Riceverai molti errori in cui semplicemente non riesce a tenere il passo.

E ricorda, i SERVIZI web richiedono ogni volta una nuova connessione.Entra in gioco la molteplicità.Non vuoi aprire connessioni socket 5000 per servire una chiamata di funzione su una tabella.È pazzo!

In tal caso dovresti creare una funzione di aggregazione personalizzata e utilizzarla come argomento da passare al tuo servizio web, che restituirebbe un set di risultati... quindi dovresti raccoglierlo.È davvero un modo scomodo di ottenere dati.

Se stai lavorando con i livelli di compatibilità SQL 2000 e non puoi eseguire l'integrazione clr, vedi http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx

Ho lavorato per aziende grandi/globali in tutto il mondo, utilizzando i database Oracle.Utilizziamo costantemente servizi Web tramite DB con procedure di archiviazione e senza problemi, anche quelli con traffico intenso.Tutti per uso interno, intendo senza accesso a Internet, solo all'interno dello stabilimento.Consiglierei di usarlo, ma facendo molta attenzione a come lo progetti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top