¿Puede llamar a un servicio web desde código TSQL?


¿Hay alguna forma de llamar desde un procedimiento o función almacenada TSQL a un servicio web?

Author: TheEmirOfGroofunkistan, 2008-08-29

8 answers

Sí, puedes crear así

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
 19
Author: Kiran.Bakwad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-13 10:26:55

Seguro que puedes , pero esta es una idea terrible.

Como las llamadas al servicio web pueden tomar cantidades arbitrarias de tiempo y fallar aleatoriamente, dependiendo de cuántos juegos de counterstrike se estén jugando en su red en ese momento, no puede decir cuánto tiempo tomará esto.

Como mínimo, probablemente esté viendo medio segundo cuando compila el XML, envía la solicitud HTTP al servidor remoto, que luego tiene que analizar el XML y enviar una respuesta volver.

  1. Cualquiera que sea la aplicación que hizo la consulta INSERT INTO BLAH que causó que el servicio web se activara tendrá que esperar a que termine. A menos que esto sea algo que solo sucede en segundo plano como una tarea diaria programada, el rendimiento de su aplicación va a explotar

  2. El código que invoca el servicio web se ejecuta dentro de SQL Server y consume sus recursos. Como va a tomar mucho tiempo esperar la solicitud HTTP, terminará consumiendo una gran cantidad de recursos, que volverá a dañar el rendimiento de su servidor.

 20
Author: Orion Edwards,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-01 20:33:42

No en el código T-SQL en sí, pero con SQL Server 2005 y superiores, han habilitado la capacidad de escribir procedimientos almacenados CLR, que son esencialmente funciones en código.NET y luego exponerlos como procedimientos almacenados para su consumo. Tienes la mayor parte de.NET framework a tu alcance para esto, así que puedo ver el consumo de un servicio web posible a través de esto.

Es un poco largo para discutir en detalle aquí, pero aquí hay un enlace a un artículo de MSDN sobre el tema.

 9
Author: Dillie-O,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-08-28 21:34:57

No haría esto por tráfico pesado o cosas de misión crítica, SIN EMBARGO, si NO necesita recibir comentarios de un servicio, entonces es realmente una gran cosa que hacer.

He aquí un ejemplo de lo que he hecho.

  1. Desencadenadores Insertar y Actualizar en una tabla
  2. Desencadenador llamado Proc almacenado que pasa los datos JSON de la transacción a un punto final de Api Web que luego se inserta en un MongoDB en AWS.

No hagas XML antiguo

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) 

Ejemplo 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
 4
Author: Tom Stickel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-17 17:30:25

En versiones anteriores de Sql, se podía usar un proc almacenado extendido o xp_cmdshell para shell y llamar a un servicio web.

No es que ninguno de estos suene como una arquitectura decente, pero a veces tienes que hacer cosas locas.

 3
Author: Mark Brackett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-06 21:40:54

Puede hacerlo con los objetos VB incrustados.

Primero se crea un objeto VB de tipo 'MSXML2.XMLHttp', y usa este objeto para todas sus consultas (si lo vuelve a crear cada vez, espere una penalización de rendimiento pesada).

Luego alimenta ese objeto, algunos parámetros, en un procedimiento almacenado que invoca sp_OAMethod en el objeto.

Lo siento por el ejemplo inprecise, pero una búsqueda rápida en Google debería revelar cómo es el método vb-script Terminado.

--

Pero la versión CLR es mucho....Mucho más fácil. El problema con la invocación de servicios web es que no pueden seguir el ritmo del motor de base de datos. Obtendrá muchos errores donde simplemente no puede mantenerse al día.

Y recuerde, los SERVICIOS web requieren una nueva conexión cada vez. La multiplicidad entra en juego. No desea abrir conexiones de socket 5000 para dar servicio a una llamada de función en una tabla. Eso es looney!

En ese caso, tendría que crear una función de agregado personalizada, y úselo como un argumento para pasar a su servicio web, que devolvería un conjunto de resultados...entonces tendrías que cotejar eso. Es realmente una forma incómoda de obtener datos.

 2
Author: Brian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-22 17:04:20

Si trabaja con niveles de compatibilidad sql 2000 y no puede integrar clr, consulte http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx

 1
Author: bander,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-12-23 20:53:34

De acuerdo en que no es algo que quieras hacer, sin embargo, a veces tienes que hacer cosas que idealmente no te gusta hacer. En este caso terminé reescribiendo la función de servicio web como una función sql para realizar la misma tarea.

Gracias por todos los enlaces y sugerencias.

 0
Author: TheEmirOfGroofunkistan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-03 17:09:38