• We're off-topic a bit (not talking about Geocoding any more, but rather calling an arbitrary web service). That's OK...

    When I run your code (with either URL) I am getting:

    Error in spNS: HTTP result is: 401

    So the code is working, but the server is returning an HTTP 401 code (unauthorized)

    The problem is that the MSXML2.ServerXMLHttp supports providing username / password credentials via properties, but not embedded in the URL.

    You can use an updated GetHTTP routine(see below) that accepts username and password. You can use it like this:

    DECLARE @MyResults varchar(MAX)

    DECLARE @HTTPStatus int

    EXEC dbo.sputilGetHTTP

    @URL = 'http://webservices.ns.nl/ns-api-treinplanner?fromStation=Utrecht+Centraal&toStation=Wierden&departure=true',

    @User = 'username',

    @Password = 'password',

    @ResponseText = @MyResults OUTPUT,

    @HTTPStatus = @HTTPStatus OUTPUT

    SELECT

    @HTTPStatus AS HTTPStatus,

    @MyResults AS Response

    Here is the code for the updated spGetHTTP procedure:

    CREATE PROCEDURE [dbo].[sputilGetHTTP]

    @URL varchar(MAX),

    --URL to retrieve data from

    @HTTPMethod varchar(40) = 'GET',

    --can be either GET or POST

    @ContentType varchar(80)= 'text/http',

    --set to 'application/x-www-form-urlencoded' for POST, etc.

    @DataToSend nvarchar(4000) = NULL,

    --data to post, if @HTTPMethod = 'POST'

    @HTTPStatus int = NULL OUTPUT,

    --HTTP Status Code (200=OK, 404=Not Found, etc.)

    @HTTPStatusText nvarchar(4000) = NULL OUTPUT,

    @ResponseText nvarchar(MAX) = NULL OUTPUT,

    --Full text returned by remote HTTP server (if @SuppressResponseText = 0)

    @ErrorMsg varchar(MAX) = NULL OUTPUT,

    --NULL unless an error message was encountered

    @LastResultCode int = NULL OUTPUT,

    --0 unless an error code was returned by MSXML2.ServerXMLHttp

    @User varchar(512) = NULL,

    --If provided, use this value for the HTTP authentication user name

    @Password varchar(512) = NULL,

    --If provided, use this value for the HTTP authentication password

    @SuppressResponseText bit = 0,

    --If 0, actual content is not returned from remote server (just status code)

    @SuppressResultset bit = 1,

    --If 0, result set is is not returned (just parameters)

    @SilenceErrors bit = 0

    --If 1, errors are not raised with RAISEERROR(), but caller can check @ErrorMsg.

    --@ErrorMsg will be null if no error was raised.

    --Written by David Rueter (drueter@assyst.com)

    AS

    BEGIN

    --Retrieves data via HTTP

    --http://msdn.microsoft.com/en-us/library/aa238861(v=sql.80).aspx

    SET NOCOUNT ON

    DECLARE @Debug bit

    SET @Debug = 0

    DECLARE @CRLF varchar(5)

    SET @CRLF = CHAR(13) + CHAR(10)

    DECLARE @Obj int

    DECLARE @PerformedInit bit

    SET @PerformedInit = 0

    DECLARE @ErrSource varchar(512)

    DECLARE @ErrMsg varchar(512)

    DECLARE @tvResponse TABLE (Response nvarchar(MAX))

    SET @ErrorMsg = NULL

    IF @Debug = 1 PRINT 'About to call sp_OACreate for MSXML2.ServerXMLHttp'

    BEGIN TRY

    EXEC @LastResultCode = sp_OACreate 'MSXML2.ServerXMLHttp', @Obj OUT

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    ELSE BEGIN

    SET @PerformedInit = 1

    END

    END TRY

    BEGIN CATCH

    SET @ErrorMsg = ERROR_MESSAGE()

    END CATCH

    BEGIN TRY

    IF @LastResultCode = 0 BEGIN

    IF @HTTPMethod = 'GET' BEGIN

    IF @Debug = 1 PRINT 'About to call sp_OAMethod for open (GET)'

    EXEC @LastResultCode = sp_OAMethod @Obj, 'open', NULL, 'GET', @URL, false, @User, @Password

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    END

    ELSE BEGIN

    IF @Debug = 1 PRINT 'About to call sp_OAMethod for open (POST)'

    EXEC @LastResultCode = sp_OAMethod @Obj, 'open', NULL, 'POST', @URL, false, @User, @Password

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    IF @Debug = 1 PRINT 'About to call sp_OAMethod for setRequestHeader'

    IF @LastResultCode = 0 EXEC @LastResultCode = sp_OAMethod @Obj, 'setRequestHeader', NULL, 'Content-Type', @ContentType

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    END

    END

    IF @Debug = 1 PRINT 'About to call sp_OAMethod for send'

    IF @LastResultCode = 0 EXEC @LastResultCode = sp_OAMethod @Obj, 'send', NULL, @DataToSend

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    IF @LastResultCode = 0 EXEC @LastResultCode = sp_OAGetProperty @Obj, 'status', @HTTPStatus OUT

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    IF @LastResultCode = 0 EXEC @LastResultCode = sp_OAGetProperty @Obj, 'statusText', @HTTPStatusText OUT

    IF @LastResultCode <> 0 BEGIN

    EXEC sp_OAGetErrorInfo @obj, @ErrSource OUTPUT, @ErrMsg OUTPUT

    END

    IF (@LastResultCode = 0) AND (ISNULL(@SuppressResponseText, 0) = 0) BEGIN

    INSERT INTO @tvResponse (Response)

    EXEC @LastResultCode = sp_OAGetProperty @Obj, 'responseText' --, @Response OUT

    --Note: sp_OAGetProperty (or any extended stored procedure parameter) does not support

    --varchar(MAX), however returning as a resultset will return long results.

    END

    END TRY

    BEGIN CATCH

    SET @ErrorMsg = ERROR_MESSAGE()

    END CATCH

    DECLARE @DestroyResultCode int

    EXEC @DestroyResultCode = sp_OADestroy @Obj

    SELECT @ResponseText = Response FROM @tvResponse

    SET @ErrorMsg =

    NULLIF(RTRIM(

    ISNULL(@ErrorMsg, '') +

    ISNULL(' (' + @ErrMsg + ')', '') +

    ISNULL(' [' + @ErrSource + ']', '')

    ), '')

    IF @ErrorMsg IS NOT NULL BEGIN

    SET @ErrorMsg = 'Error in sputilGetHTTP: ' + @ErrorMsg

    IF @PerformedInit = 0 BEGIN

    SET @ErrorMsg = @ErrorMsg + @CRLF +

    'Remember that this stored procedure uses OLE. To work properly you may need to configure ' +

    'your database to allow OLE, as follows: ' + @CRLF +

    ' EXEC sp_configure ''show advanced options'', 1;' + @CRLF +

    ' RECONFIGURE;' + @CRLF +

    ' EXEC sp_configure ''Ole Automation Procedures'', 1;' + @CRLF +

    ' RECONFIGURE;' + @CRLF +

    'Also, your SQL user must have execute rights to the following stored procedures in master:' + @CRLF +

    ' sp_OACreate' + @CRLF +

    ' sp_OAGetProperty' + @CRLF +

    ' sp_OASetProperty' + @CRLF +

    ' sp_OAMethod' + @CRLF +

    ' sp_OAGetErrorInfo' + @CRLF +

    ' sp_OADestroy' + @CRLF +

    'You can grant rights for each of these as follows:' + @CRLF +

    ' USE master' + @CRLF +

    ' GRANT EXEC ON sp_OACreate TO myuser' + @CRLF +

    ' GRANT EXEC etc. ...'

    IF ISNULL(@SilenceErrors, 0) = 0 BEGIN

    RAISERROR(@ErrorMsg, 16, 1)

    END

    END

    END

    IF ISNULL(@SuppressResultset, 0) = 0 BEGIN

    SELECT

    @URL AS URL,

    @ResponseText AS ResponseText,

    @HTTPStatus AS HTTPStatus,

    @LastResultCode AS LastResultCode,

    @ErrorMsg AS ErrorMsg

    END

    END