Puoi chiamare un webservice dal codice TSQL?

C’è un modo per chiamare da una stored procedure TSQL o una funzione a un servizio web?

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 

Certo che puoi , ma questa è una pessima idea.

Dal momento che le chiamate al servizio web possono richiedere una quantità arbitraria di tempo e falliscono casualmente, a seconda del numero di giochi di counterstrike che vengono riprodotti sulla rete in quel momento, non è ansible stabilire per quanto tempo ciò avverrà.

Al minimo si sta osservando probabilmente mezzo secondo per quando si costruisce l’XML, si invia la richiesta HTTP al server remoto, che quindi deve analizzare l’XML e inviare una risposta.

  1. Qualunque applicazione abbia fatto la query INSERT INTO BLAH che ha causato l’ INSERT INTO BLAH del servizio web, dovrà attendere che finisca. A meno che non si tratti di qualcosa che accade solo in background come un’attività programmata quotidianamente, la performance della tua app sta per esplodere

  2. Il codice di richiamo del 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 stesso, ma con SQL Server 2005 e versioni successive, hanno abilitato la possibilità di scrivere stored procedure CLR, che sono essenzialmente funzioni nel codice .NET e quindi esporle come stored procedure per il consumo. A tal fine, la maggior parte del framework .NET è a portata di mano, quindi posso vedere il consumo di un servizio Web ansible attraverso questo.

È un po ‘lungo discutere in dettaglio qui, ma ecco un link a un articolo di MSDN sull’argomento.

Non lo farei per il traffico pesante o le cose di importanza critica, TUTTAVIA, se NON hai bisogno di ricevere feedback da un servizio, allora è davvero una grande cosa da fare.

Ecco un esempio di ciò che ho fatto.

  1. Trigger Inserisci e aggiorna su un tavolo
  2. Trigger chiamato Stored Proc che passa i dati JSON della transazione a un Web Api Endpoint che quindi inserisce in un MongoDB in AWS.

Non fare 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, è ansible utilizzare un proc esteso memorizzato o xp_cmdshell per eseguire il shell out e chiamare un webservice.

Non che nessuno di questi suoni come un’architettura decente – ma a volte devi fare cose pazzesche.

Puoi farlo con gli oggetti VB incorporati.

Per prima cosa si crea un object VB di tipo “MSXML2.XMLHttp” e si utilizza questo object per tutte le query (se lo si ricrea ogni volta si prevede una pesante penalizzazione delle prestazioni).

Quindi si alimenta quell’object, alcuni parametri, in una stored procedure che richiama sp_OAMethod sull’object.

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ù facile. Il problema con il richiamo dei servizi Web è che non riescono a tenere il passo con il motore DB. Avrai molti errori in cui non riesco a tenere il passo.

E ricorda, i servizi web richiedono una nuova connessione ogni volta. La molteplicità entra in gioco. Non si desidera aprire 5000 connessioni socket per gestire una chiamata di funzione su un tavolo. Quello è looney!

In tal caso dovresti creare una funzione di aggregazione personalizzata e usare THAT come argomento da passare al tuo webservice, che restituirebbe un set di risultati … quindi dovresti metterlo in pratica. È davvero un modo scomodo di ottenere dati.

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

Ho convenuto che non è qualcosa che voglio fare, tuttavia a volte devi fare cose che non ti piace fare. In questo caso ho finito per riscrivere la funzione del servizio web come una funzione sql per eseguire lo stesso compito.

Grazie per tutti i link e i suggerimenti.