Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
следующий код на VBA у меня работает

Dim rq As WinHttp.WinHttpRequest
  
  Set rq = New WinHttpRequest
  
  rq.Open "POST", Me.txtURI.Value, 0 ' в Me.txtURI.Value лежит 'http://www.ru''
  rq.SetRequestHeader "Content-Type", "application/x-www-form-urlencoded"
  rq.SetRequestHeader "Content-Length", CStr(Len(Me.txtPost.Value))
  
  rq.Send Me.txtPost.Value ' в Me.txtPost.Value лежит '123=0&5=6&sql=not sql''
  Me.txtReply = rq.ResponseText
в ResponseText получаю содержимое страницы

а то же самое на T-SQL, на мой взгляд, возвращает мне NULL в @responseText
declare
@URI varchar(2000),
@methodName varchar(50),
@requestBody varchar(8000),
@responseText varchar(8000),
@proxy varchar(50), 
@proxySettings varchar(50)

select @URI='http://www.ru',@methodName='POST',@requestBody='123=0&5=6&sql=not sql'


DECLARE @objectID int
DECLARE @hResult int
DECLARE @source varchar(255), @desc varchar(255)

EXEC 	@hResult = sp_OACreate 'WinHttp.WinHttpRequest.5.1', @objectID OUT

IF @hResult <> 0
BEGIN
	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
	SELECT 	hResult = convert(varbinary(4), @hResult), 
			source = @source, 
			description = @desc,
			FailPoint = 'Create failed',
			MedthodName = @methodName
	goto destroy
	return
END

-- open the destination URI with Specified method
EXEC @hResult = sp_OAMethod @objectID, 'open', null, @methodName, @URI, 'false'
IF @hResult <> 0
BEGIN
	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
	SELECT 	hResult = convert(varbinary(4), @hResult), 
		source = @source, 
		description = @desc,
		FailPoint = 'Open failed',
		MedthodName = @methodName
	goto destroy
	return
END

-- set request headers
EXEC @hResult = sp_OAMethod @objectID, 'setRequestHeader', null, 'Content-Type', 'application/x-www-form-urlencoded'
IF @hResult <> 0
BEGIN
	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
	SELECT 	hResult = convert(varbinary(4), @hResult), 
		source = @source, 
		description = @desc,
		FailPoint = 'SetRequestHeader failed: Content-Type',
		MedthodName = @methodName
	goto destroy
	return
END

declare @len int
set @len = len(@requestBody)
EXEC @hResult = sp_OAMethod @objectID, 'setRequestHeader', null, 'Content-Length', @len
IF @hResult <> 0
BEGIN
	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
	SELECT 	hResult = convert(varbinary(4), @hResult), 
		source = @source, 
		description = @desc,
		FailPoint = 'SetRequestHeader failed: Content-Length',
		MedthodName = @methodName
	goto destroy
	return
END
--
--EXEC @hResult = sp_OAMethod @objectID, 'setProxy', NULL,  @proxy, @proxySettings
--IF @hResult <> 0
--BEGIN
--	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
--	SELECT 	hResult = convert(varbinary(4), @hResult), 
--		source = @source, 
--		description = @desc,
--		FailPoint = 'SetProxy'
--	goto destroy
--	return
--END

-- send the request
select 	requestBody = @requestBody
EXEC 	@hResult = sp_OAMethod @objectID, 'send', null, @requestBody
IF 	@hResult <> 0
BEGIN
	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
	SELECT 	hResult = convert(varbinary(4), @hResult), 
		source = @source, 
		description = @desc,
		FailPoint = 'Send failed',
		MedthodName = @methodName
	goto destroy
	return
END

declare @statusText varchar(1000), @status varchar(1000)
-- Get status text
exec sp_OAGetProperty @objectID, 'StatusText', @statusText out 
exec sp_OAGetProperty @objectID, 'Status', @status out 
select hResult=@hResult, status=@status, statusText=@statusText, methodName=@methodName

-- Get response text
exec sp_OAGetProperty @objectID, 'responseText', @responseText out 
select responseText=@responseText

IF @hResult <> 0
BEGIN
	EXEC sp_OAGetErrorInfo @objectID, @source OUT, @desc OUT 
	SELECT 	hResult = convert(varbinary(4), @hResult), 
		source = @source, 
		description = @desc,
		FailPoint = 'ResponseText failed',
		MedthodName = @methodName
	goto destroy
	return
END

destroy:
	exec sp_OADestroy @objectID

SET nocount off

GO
26 июл 09, 15:12    [7461115]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Glory
Member

Откуда:
Сообщений: 104760
Shurgenz


а то же самое на T-SQL, на мой взгляд, возвращает мне NULL в @responseText

Ну а запрос то к удаленному веб серверу уходит ?
27 июл 09, 10:23    [7462221]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
Glory
Shurgenz


а то же самое на T-SQL, на мой взгляд, возвращает мне NULL в @responseText

Ну а запрос то к удаленному веб серверу уходит ?


уходит
по крайней мере
EXEC 	@hResult = sp_OAMethod @objectID, 'send', null, @requestBody
отрабатывает без ошибки
27 июл 09, 15:26    [7464810]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Glory
Member

Откуда:
Сообщений: 104760
Shurgenz
Glory
Shurgenz


а то же самое на T-SQL, на мой взгляд, возвращает мне NULL в @responseText

Ну а запрос то к удаленному веб серверу уходит ?


уходит
по крайней мере
EXEC 	@hResult = sp_OAMethod @objectID, 'send', null, @requestBody
отрабатывает без ошибки

Под "уходит" я вообще понимал, что видно в логе какого-нибудь прокси виден запрос от учетной записи сервера к удаленному ресурсу
27 июл 09, 15:42    [7464928]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
Я так понимаю, что если на VBA у меня запрос к серверу уходит и возвращает результат, используя одну и ту же библиотеку и один и тот же метод, то должен уходить ивозвращать тот жерезультат и на T-SQL?

Я потому и привел здесь 2 кода на разных языках выполняющих по моему мнению одно и то же.... Да видимо один код от другого отличается... а чем, понять не могу
27 июл 09, 15:52    [7465001]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Shurgenz
Я так понимаю, что если на VBA у меня запрос к серверу уходит и возвращает результат, используя одну и ту же библиотеку и один и тот же метод, то должен уходить ивозвращать тот жерезультат и на T-SQL?
...

не факт, результат разный например может быть из-за того что запросы выполняются под разными учётками.
27 июл 09, 16:02    [7465058]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Glory
Member

Откуда:
Сообщений: 104760
Shurgenz
Я так понимаю, что если на VBA у меня запрос к серверу уходит и возвращает результат, используя одну и ту же библиотеку и один и тот же метод, то должен уходить ивозвращать тот жерезультат и на T-SQL?

Я потому и привел здесь 2 кода на разных языках выполняющих по моему мнению одно и то же.... Да видимо один код от другого отличается... а чем, понять не могу

А вы ваш код VBA как то тестируете из под учетной записи сервера ?
27 июл 09, 16:02    [7465060]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
Glory
Shurgenz
Я так понимаю, что если на VBA у меня запрос к серверу уходит и возвращает результат, используя одну и ту же библиотеку и один и тот же метод, то должен уходить ивозвращать тот жерезультат и на T-SQL?

Я потому и привел здесь 2 кода на разных языках выполняющих по моему мнению одно и то же.... Да видимо один код от другого отличается... а чем, понять не могу

А вы ваш код VBA как то тестируете из под учетной записи сервера ?


Хм, сервер стартован под админской учетной записью... под ней же я залогинен на сервере. Я полагаю, что права одинаковы, если Вы это имеете в виду
27 июл 09, 16:39    [7465326]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Shurgenz,
Есть ли возможность проверить логи веб сервера к которому идёт запрос?
На сервере (от которого идёт запрос) установлен фаервол\антивирус?
27 июл 09, 16:46    [7465379]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
фаервол и антивирус установлены
проверить логи не могу.... ресурс в качестве теста выбран www.ru
27 июл 09, 16:52    [7465433]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Shurgenz,
Запустил sql-скрипт, на 'http://www.ru' вернул null. Поменял адрес на локалхост - вернул что надо.
Может проблема в том что www.ru возращачет более 11тыщ. символов(запускал пример VBA) ?
27 июл 09, 17:56    [7465814]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
Сергей Мишин
Shurgenz,
Запустил sql-скрипт, на 'http://www.ru' вернул null. Поменял адрес на локалхост - вернул что надо.
Может проблема в том что www.ru возращачет более 11тыщ. символов(запускал пример VBA) ?


и правда, интересно получается

каково же ограничение на responseText в T-SQL?

Код в VBA возвращает текст с www.ru, как впрочем и sql.ru и других немаленьких по контенту сай тов

Пробовал ресурс с небольшим контентом, T-SQL код возвращает не NULL в responseText
Пробовал менять тип @responseText varchar(8000) на varchar(max), проблема не решилась, видимо она где-то выше.
27 июл 09, 18:36    [7465989]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Shurgenz,

Проблема не в самом методе responseText, а похоже в том что sp_OAGetProperty не может вернуть более 8000 символов.

Первое что пришло в голову - изменить способ вызова:
-- Get response text
CREATE TABLE #t (r varchar(max))
INSERT #t
	exec sp_OAGetProperty @objectID, 'ResponseText'--, @responseText out 
select * FROM #t
27 июл 09, 18:57    [7466055]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6722
Семикратная копи-паста sp_OAGetErrorInfo. Буээээ.
Да и прокси можно/нужно управлять на уровне учётки.

Shurgenz
Пробовал ресурс с небольшим контентом, T-SQL код возвращает не NULL в responseText
Пробовал менять тип @responseText varchar(8000) на varchar(max), проблема не решилась, видимо она где-то выше.
Мда, грабли вещь очень эффективная, ибо никогда не останутся без работы.

Вот "черновой" вариант работы c Web сервисом. Постом выше вариант без парциального чтения - через INSERT EXEC, а она как мы знаем весчь капризная ибо не работает при плохой погоде. Так что доступ к файловой системе оказался необходим.

Кстати, никто так и не предложил вариант "чистого" чтения OLE переменной более 8K: и без INSERT EXEC и без доступа к файловой системе.
27 июл 09, 22:32    [7466517]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Mnior
...через INSERT EXEC, а она как мы знаем весчь капризная ибо не работает при плохой погоде...

а в чём выражается эта "плохая погода" ? -)
28 июл 09, 09:56    [7467156]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6722
Если внутри этого EXEC будет ещё один INSERT EXEC, а ещё в брокере, если ничего не путаю, или "игры" с транзакциями внутри. Блин, память дырявая. :(
Короче конструкция INSERT EXEC от лукавого, грабли могут выйти в самый неподходящих местах и моментах. Риск с этим надо оценивать.

В одно время игрался, как через MemoryStream сделать, но тогда упёрся в ограничения работы OLE Automation по созданию дочернего или просто нового связанного объекта.

Может ктось сможет засунуть значение переменной в Strеam или подстроки резать?
28 июл 09, 14:53    [7469163]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
Господа, с получением текста ответа получилось и замечательно работает.

Но сколько ни бился, не получилось передать @requestBody на сервер

что нужно сделать чтобы передать нечто типа

http://www.ru?someparam=somedata?

я полагал, что в данном случае в @URI будет http://www.ru
а в @requestBody что-то из someparam=somedata или ?someparam=somedata
но ни то ни другое к нужному результату не привело

запущенное в бровзере http://www.ru?someparam=somedata отработало прекрасно, передав нужный параметр веб странице, а из скрипта веб страница этого параметра не получает, как будто его и нет вовсе
31 июл 09, 14:28    [7484800]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Shurgenz,
Надо отправить данные методом GET, а url указать @URI='http://www.ru/?someparam=somedata'
@requestBody надо это для метода POST
31 июл 09, 15:32    [7485345]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Shurgenz
Member

Откуда: Питер
Сообщений: 1931
Спасибо большое :) вечерком попробую
31 июл 09, 15:35    [7485379]     Ответить | Цитировать Сообщить модератору
 Re: WinHttp.WinHttpRequest.5.1 POST метод  [new]
Сергей Мишин
Member

Откуда:
Сообщений: 376
Shurgenz,
Если надо отправить методом GET, то напримере яндекса будет примерно так:
DECLARE @URI varchar(2000), @methodName varchar(50)

SELECT @URI='http://yandex.ru/yandsearch?text=sql',@methodName='GET'

DECLARE @objectID int, @hResult int

EXEC 	@hResult = sp_OACreate 'WinHttp.WinHttpRequest.5.1', @objectID OUT
IF @hResult <> 0 goto destroy

EXEC @hResult = sp_OAMethod @objectID, 'open', null, @methodName, @URI, 'false'
IF @hResult <> 0 goto destroy

EXEC 	@hResult = sp_OAMethod @objectID, 'send', null
IF @hResult <> 0 goto destroy

DECLARE @t TABLE(s nvarchar(max))
INSERT @t
	EXEC sp_OAGetProperty @objectID, 'responseText'
IF @hResult <> 0 goto destroy

--Вывод:
DECLARE @s nvarchar(max),@i int
SELECT @s = s,@i=1 FROM @t
WHILE @i < len(@s) BEGIN
	PRINT substring(@s,@i,4000)
	SET @i = @i + 4000
END

destroy:
	exec sp_OADestroy @objectID
где '?text=sql' в урл и есть параметры передаваемые серверному скрипту.
31 июл 09, 16:03    [7485552]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить