Можете ли вы вызвать веб-сервис из кода TSQL?
-
09-06-2019 - |
Вопрос
Есть ли способ вызвать из хранимой процедуры или функции TSQL веб-сервис?
Решение
Да, вы можете создавать подобное
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
Другие советы
Уверен, что ты может, но это ужасная идея.
Поскольку вызовы веб-служб могут занимать произвольное количество времени и случайно завершаться сбоем, в зависимости от того, сколько игр counterstrike воспроизводится в вашей сети в данный момент, вы не можете сказать, сколько времени это займет.
Как минимум, вам потребуется, вероятно, полсекунды к тому времени, когда он соберет XML, отправит HTTP-запрос на удаленный сервер, который затем должен проанализировать XML и отправить ответ обратно.
Какое бы приложение ни выполняло
INSERT INTO BLAH
запросу, который вызвал запуск веб-службы, придется дождаться ее завершения.Если это не происходит только в фоновом режиме, как ежедневное запланированное задание, производительность вашего приложения резко упадетКод, вызывающий веб-службу, выполняется внутри SQL server и использует его ресурсы.Поскольку ожидание HTTP-запроса займет много времени, вы в конечном итоге израсходуете много ресурсов, что снова снизит производительность вашего сервера.
Не в самом коде T-SQL, но в SQL Server 2005 и выше они включили возможность писать хранимые процедуры CLR, которые по сути являются функциями в коде .NET, а затем предоставлять их как хранимые процедуры для использования.Для этого у вас под рукой есть большая часть .NET framework, поэтому я вижу, что с помощью этого возможно использование веб-сервиса.
Это немного долго обсуждать подробно здесь, но вот ссылка на Статья в MSDN по теме.
Я бы не стал этого делать из-за интенсивного трафика или критически важных задач, ОДНАКО, если вам НЕ нужно получать обратную связь от сервиса, то это действительно отличное занятие.
Вот пример того, что я сделал.
- Запускает вставку и обновление таблицы
- Триггер, вызываемый хранимым процессом, который передает JSON-данные транзакции в конечную точку веб-Api, которая затем вставляется в MongoDB в AWS.
Не используйте старый 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)
Полный пример:
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
В более ранних версиях Sql вы могли использовать либо расширенный хранимый proc, либо xp_cmdshell для развертывания и вызова веб-сервиса.
Не то чтобы что-то из этого звучало как приличная архитектура, но иногда приходится делать сумасшедшие вещи.
Вы можете сделать это с помощью встроенных объектов VB.
Сначала вы создаете один объект VB типа 'MSXML2.XMLHttp' и используете этот объект для всех своих запросов (если вы будете воссоздавать его каждый раз, ожидайте значительного снижения производительности).
Затем вы передаете этот объект, некоторые параметры, в хранимую процедуру, которая вызывает sp_OAMethod для объекта.
Извините за неточный пример, но быстрый поиск в Google должен показать, как выполняется метод vb-script.
--
Но версия CLR намного лучше....НАМНОГО проще.Проблема с вызовом веб-сервисов заключается в том, что они не могут идти в ногу с механизмом базы данных.Вы получите множество ошибок, за которыми он просто не сможет угнаться.
И помните, что веб-СЛУЖБАМ каждый раз требуется новое подключение.В игру вступает множественность.Вы не хотите открывать 5000 подключений к сокетам для обслуживания вызова функции в таблице.Это псих!
В этом случае вам пришлось бы создать пользовательскую агрегатную функцию и использовать ЕЕ в качестве аргумента для передачи вашему веб-сервису, который вернул бы результирующий набор...затем вам нужно было бы сопоставить это.Это действительно неудобный способ получения данных.
Если вы работаете с уровнями совместимости sql 2000 и не можете выполнить интеграцию с clr, см. http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx
Я работал в крупных / глобальных компаниях по всему миру, используя базы данных Oracle.Мы постоянно используем веб-сервисы через базу данных с процедурами хранения и без проблем, даже с большим трафиком.Все они предназначены для внутреннего использования, я имею в виду без доступа к Интернету, только внутри завода.Я бы рекомендовал использовать его, но будьте очень осторожны с тем, как вы его разрабатываете