Pregunta

¿Existe alguna forma de llamar desde una función o procedimiento almacenado TSQL a un servicio web?

¿Fue útil?

Solución

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

Otros consejos

Seguro poder, pero esta es una idea terrible.

Como las llamadas al servicio web pueden tardar 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 se puede saber cuánto tiempo llevará.

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

  1. Cualquiera que sea la aplicación INSERT INTO BLAH La consulta que provocó que se activara el servicio web tendrá que esperar a que finalice.A menos que esto sea algo que solo suceda en segundo plano, como una tarea programada diariamente, el rendimiento de su aplicación será una bomba.

  2. El código que invoca el servicio web se ejecuta dentro del servidor SQL y consume sus recursos.Como llevará mucho tiempo esperar la solicitud HTTP, terminará consumiendo muchos recursos, lo que nuevamente afectará el rendimiento de su servidor.

No en el código T-SQL en sí, pero con SQL Server 2005 y versiones posteriores, 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.Para esto, tiene la mayor parte del marco .NET a su alcance, por lo que puedo ver posible el consumo de un servicio web a través de esto.

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

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

Aquí hay un ejemplo de lo que he hecho.

  1. Activadores Insertar y Actualizar en una Tabla
  2. Activador llamado Stored Proc que pasa los datos JSON de la transacción a un punto final de Web Api que luego se inserta en 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

En versiones anteriores de Sql, podía utilizar un proceso almacenado extendido o xp_cmdshell para desembolsar y llamar a un servicio web.

No es que ninguna de estas cosas parezca una arquitectura decente, pero a veces hay que hacer cosas locas.

Puedes hacerlo con los objetos VB incrustados.

Primero, crea un objeto VB de tipo 'MSXML2.XMLHttp' y utiliza este objeto para todas sus consultas (si lo vuelve a crear cada vez, esperará una gran penalización en el rendimiento).

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

Perdón por el ejemplo inexacto, pero una búsqueda rápida en Google debería revelar cómo se realiza el método vb-script.

--

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 en los que simplemente no podrá seguir el ritmo.

Y recuerda, los SERVICIOS web requieren una nueva conexión cada vez.La multiplicidad entra en juego.No desea abrir 5000 conexiones de socket para atender una llamada de función en una mesa.¡Eso es una locura!

En ese caso, tendría que crear una función agregada personalizada y usar ESO como argumento para pasar a su servicio web, lo que devolvería un conjunto de resultados... luego tendría que cotejar eso.Es realmente una forma incómoda de obtener datos.

Si está trabajando con niveles de compatibilidad de SQL 2000 y no puede realizar la integración clr, consulte http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx

He estado trabajando para empresas grandes y globales de todo el mundo, utilizando bases de datos Oracle.Consumimos servicios web todo el tiempo a través de DB con procedimientos de tienda y sin problemas, incluso aquellos con mucho tráfico.Todos ellos para uso interno, es decir sin acceso a internet, sólo dentro de la planta.Recomendaría usarlo pero teniendo mucho cuidado con cómo lo diseñas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top