2014-10-06 6 views
4

Я пытаюсь создать хранимую процедуру в TSQL для вызова веб-службы. Я делал это раньше в Oracle, но, похоже, в MSSQL это не так просто. Есть, конечно, много причин не делать этого в хранимой процедуре, но поскольку эту процедуру нужно использовать только в ежедневной партии, производительность не слишком большая проблема. Я хочу сделать следующее: Отправить полное имя в webservice, веб-сервис вернет имя, разделенное на такие вещи, как имя, префикс, фамилия и т. Д. Возвращенные значения должны быть записаны в таблицу.Вызов веб-службы SOAP из хранимой процедуры TSQL

Я нашел интересную процедуру на http://www.vishalseth.com/post/2009/12/22/Call-a-webservice-from-TSQL-(Stored-Procedure)-using-MSXML.aspx, которая, казалось, выполняла именно то, что я хочу, но как только вы добавляете тело в вызов, я сталкива Об этом также говорится в статье, и, по-видимому, для этого нет простого решения. Мне определенно нужно отправить тело запроса.

Я также прочитал много статей о его решении с помощью CLI или «Редактор заданий веб-службы» или «SSIS». Я не мог найти никаких учебных пособий о том, с чего начать. Сейчас у меня только студия управления сервером Microsoft SQL.

Я, кстати, на SQL-сервере 2012 года.

Любые идеи о том, в каком направлении мне следует идти?

Я уже нашел это описание, которое кажется довольно чистым: http://www.databasejournal.com/features/mssql/article.php/3821271/Calling-a-Web-Service-from-within-SQL-Server.htm Однако после установки visual studio 2012 и создания «проекта базы данных SQL Server» я не могу выбрать «Добавить веб-ссылку» в контекстном меню решения , в меню есть только такая опция.

+0

Получили ли вы к решению? Я сейчас в той же ситуации –

ответ

4

В прошлом я использовал следующий метод, он не может быть лучшим способом в эти дни, но он успешно работал для меня:

DECLARE @obj int, 
     @url VarChar(MAX), 
     @response VarChar(MAX), 
     @requestHeader VarChar(MAX), 
     @requestBody VarChar(MAX) 

SET @url = 'http://....' 

SET @requestBody = '<soapenv:Envelope> 
        <soapenv:Header/> 
         <soapenv:Body> 
         ... 
         </soapenv:Body> 
        </soapenv:Envelope>' 

EXEC sp_OACreate 'MSXML2.ServerXMLHttp', @obj OUT 
EXEC sp_OAMethod @obj, 'Open', NULL, 'GET', @url, false 
EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Type', 'text/xml;charset=UTF-8' 
EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'SOAPAction', 'POST' 
EXEC sp_OAMethod @obj, 'setRequestHeader', NULL, 'Content-Length', LEN(@requestBody) 
EXEC sp_OAMethod @obj, 'send', NULL, @requestBody 
EXEC sp_OAGetProperty @obj, 'responseText', @response OUT 


SELECT @response [RESPONSE] 

EXEC sp_OADestroy @obj 

Я использовал это, чтобы вызвать WebService, который производит отчет и отправляет его по электронной почте в рамках метода.

+0

Это вроде тот же код, что и в процедуре, на которую я ссылался. Проблема с этим кодом заключается в том, что вы не можете отправить тело контента (например, фактическое сообщение с мылом). Этот метод, по-видимому, подходит для веб-сервисов REST. – ErikL

+0

Я добавил некоторые поправки, чтобы показать, как вы можете указать тело запроса и сообщение. – Mattgb

+0

Извините, что просмотрели ваши ссылки, и они дают тот же ответ, должен быть понедельник! – Mattgb

0

Вы не можете добавить веб-ссылку обычным способом при поддержке проекта SQL Server в Visual Studio. Однако вы можете использовать утилиту WSDL для создания веб-интерфейса и добавить это в свое решение. Впоследствии вы сможете получить доступ к веб-методам, которые вы хотите использовать в хранимой процедуре CLR.

Утилиту WSDL.exe можно найти в установленном пакете Microsoft SDK, я выполнил мой запуск с использованием версии Windows 7, но простой поиск вашего hdd должен предоставить вам ваше местоположение, которое было установлено в следующем каталоге: C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin

команды для использования при запуске утилиты Wsdl.exe является:

WSDL.exe /o:(name of Visual Studio Class file) /n:(name of namespace) (address of webservice) 

, например:

WSDL.exe /o:Weather.cs /n:Weather.Test http://http://wsf.cdyne.com/WeatherWS/Weather.asmx 

В этом экземпляре будет создан файл Weather.cs, который вы можете добавить в свой проект и вызвать в своем методе.

+0

Звучит интересно, не могли бы вы рассказать мне, где я могу найти утилиту WSDL? Это что-то в VS или серверной студии управления Microsoft SQL Server? – ErikL

+0

@ ErikL Вчера у меня был выходной день, когда я узнал, как стать баристами (просто сиська :)) Я обновил свой ответ, чтобы показать, как вы могли бы называть wsdl.exe – Mattgb

2

Сделано это чудовище для собственных нужд

CREATE PROCEDURE [dbo].[RequestHttpWebService] 
@Url varchar(1024), 
@HttpMethod varchar(10), 
@ParamsValues varchar(1024), -- param1=value&param2=value 
@SoapAction varchar(1024) = null 

AS BEGIN SET NOCOUNT ON;

--set @Url = 'http://localhost/service.asmx' 
--set @HttpMethod = 'soap' 
--set @ParamsValues = 'login=tr2280&password=Qwe12345&domain=webtech.development' 
--set @SoapAction = 'Authenticate' 


if @HttpMethod in ('get','GET') and len(@ParamsValues) > 0 
begin 
    set @Url = @Url + '?' + @ParamsValues 
end 

declare @obj int 
    ,@response varchar(8000) 
    ,@responseXml xml 
    ,@status varchar(50) 
    ,@statusText varchar(1024) 
    ,@method varchar(10) = (case when @HttpMethod in ('soap','SOAP') then 'POST' else @HttpMethod end) 

exec sp_OACreate 'MSXML2.ServerXMLHttp', @obj out 
exec sp_OAMethod @obj, 'Open', null, @method, @Url, false 

if @HttpMethod in ('get','GET') 
begin 
    exec sp_OAMethod @obj, 'send' 
end 
else if @HttpMethod in ('post','POST') 
begin 
    exec sp_OAMethod @obj, 'setRequestHeader', null, 'Content-Type', 'application/x-www-form-urlencoded' 
    exec sp_OAMethod @obj, 'send', null, @ParamsValues 
end 
else if @HttpMethod in ('soap','SOAP') 
begin 
    if @SoapAction is null 
     raiserror('@SoapAction is null', 10, 1) 

    declare @host varchar(1024) = @Url 
    if @host like 'http://%' 
     set @host = right(@host, len(@host) - 7) 
    else if @host like 'https://%' 
     set @host = right(@host, len(@host) - 8) 

    if charindex(':', @host) > 0 and charindex(':', @host) < charindex('/', @host) 
     set @host = left(@host, charindex(':', @host) - 1) 
    else 
     set @host = left(@host, charindex('/', @host) - 1) 

    declare @envelope varchar(8000) = '<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><{action} xmlns="http://tempuri.org/">{params}</{action}></soap:Body></soap:Envelope>' 
    declare @params varchar(8000) = '' 

    WHILE LEN(@ParamsValues) > 0 
    BEGIN 
     declare @param varchar(256), 
       @value varchar(256) 

     IF charindex('&', @ParamsValues) > 0 
     BEGIN 

      SET @param = left(@ParamsValues, charindex('&', @ParamsValues) - 1) 
      set @value = RIGHT(@param, len(@param) - charindex('=', @param)) 
      set @param = left(@param, charindex('=', @param) - 1) 
      set @params = @params + '<' + @param + '>' + @value + '</'+ @param + '>' 
      SET @ParamsValues = right(@ParamsValues, LEN(@ParamsValues) - LEN(@param + '=' + @value + '&')) 
     END 
     ELSE 
     BEGIN 
      set @value = RIGHT(@ParamsValues, len(@ParamsValues) - charindex('=', @ParamsValues)) 
      set @param = left(@ParamsValues, charindex('=', @ParamsValues) - 1) 

      set @params = @params + '<' + @param + '>' + @value + '</'+ @param + '>' 
      SET @ParamsValues = NULL 
     END 
    END 

    set @envelope = replace(@envelope, '{action}', @SoapAction) 
    set @envelope = replace(@envelope, '{params}', @params) 

    set @SoapAction = 'http://tempuri.org/' + @SoapAction 

    print @host 
    print @SoapAction 
    print @envelope 

    exec sp_OAMethod @obj, 'setRequestHeader', null, 'Content-Type', 'text/xml; charset=utf-8' 
    exec sp_OAMethod @obj, 'setRequestHeader', null, 'Host', @host 
    exec sp_OAMethod @obj, 'setRequestHeader', null, 'SOAPAction', @SoapAction 
    exec sp_OAMethod @obj, 'send', null, @envelope 
end 

exec sp_OAGetProperty @obj, 'responseText', @response out 
exec sp_OADestroy @obj 

select @status as [status], @statusText as [statusText], @response as [response] 

END

GO

+0

большое вам спасибо ... это сделало мою работу такой легкой –

Смежные вопросы