Compartir a través de


sp_invoke_external_rest_endpoint (Transact-SQL)

Se aplica a: Azure SQL Database Base de datos SQL de Microsoft Fabric

El sp_invoke_external_rest_endpoint procedimiento almacenado invoca un punto de conexión REST HTTPS proporcionado como argumento de entrada al procedimiento.

Sintaxis

Convenciones de sintaxis de Transact-SQL

EXEC @returnValue = sp_invoke_external_rest_endpoint
  [ @url = ] N'url'
  [ , [ @payload = ] N'request_payload' ]
  [ , [ @headers = ] N'http_headers_as_json_array' ]
  [ , [ @method = ] 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' ]
  [ , [ @timeout = ] seconds ]
  [ , [ @credential = ] credential ]
  [ , @response OUTPUT ]

Argumentos

[ @url = ] N'url'

Dirección URL del punto de conexión DE REST HTTPS al que se va a llamar. @url es nvarchar(4000) sin ningún valor predeterminado.

[ @payload = ] N'request_payload'

Cadena Unicode en un formato JSON, XML o TEXT que contiene la carga que se va a enviar al punto de conexión DE REST HTTPS. Las cargas deben ser un documento JSON válido, un documento XML bien formado o texto. @payload es nvarchar(max) sin valor predeterminado.

[ @headers = ] N'headers'

Encabezados que se deben enviar como parte de la solicitud al punto de conexión DE REST HTTPS. Los encabezados deben especificarse mediante un formato JSON plano (un documento JSON sin estructuras anidadas). Los encabezados definidos en la lista de nombres de encabezados prohibidos se omitirán incluso si se pasan explícitamente en el parámetro @headers; sus valores se descartarán o reemplazarán por valores proporcionados por el sistema al iniciar la solicitud HTTPS.

El parámetro @headers es nvarchar(4000) sin ningún valor predeterminado.

[ @method = ] N'method'

Método HTTP para llamar a la dirección URL. Debe ser uno de los siguientes valores: GET, POST, PUT, PATCH, DELETE, . HEAD @method es nvarchar(6) con POST como valor predeterminado.

[ @timeout = ] segundos

Tiempo en segundos permitido para que se ejecute la llamada HTTPS. Si la respuesta y la solicitud HTTP completas no se pueden enviar y recibir dentro del tiempo de espera definido en segundos, se detiene la ejecución del procedimiento almacenado y se genera una excepción. El tiempo de espera se inicia cuando se inicia y finaliza la conexión HTTP cuando la respuesta y la carga incluida, si existe, se ha recibido. @timeout es un valor pequeño positivo con un valor predeterminado 30. Valores aceptados: de 1 a 230.

[ @credential = ] credential

Indique qué objeto DATABASE SCOPED CREDENTIAL se usa para insertar información de autenticación en la solicitud HTTPS. @credential es sysname sin ningún valor predeterminado.

@response SALIDA

Permitir que la respuesta recibida del punto de conexión llamado se pase a la variable especificada. @response es nvarchar(max).

Valor devuelto

La ejecución devolverá 0 si se realizó la llamada HTTPS y el código de estado HTTP recibido es un código de estado 2xx (Success). Si el código de estado HTTP recibido no está en el intervalo 2xx, el valor devuelto será el código de estado HTTP recibido. Si no se puede realizar la llamada HTTPS, se producirá una excepción.

Permisos

Requiere el permiso de base de datos EXECUTE ANY EXTERNAL ENDPOINT.

Por ejemplo:

GRANT EXECUTE ANY EXTERNAL ENDPOINT TO [<PRINCIPAL>];

Formato de respuesta

La respuesta de la llamada HTTP y los datos resultantes enviados por el punto de conexión invocado están disponibles a través del parámetro de salida @response . @response puede contener un documento JSON con el esquema siguiente:

{
  "response": {
    "status": {
      "http": {
        "code": "",
        "description": ""
      }
    },
    "headers": {}
  },
  "result": {}
}

Específicamente:

  • response: un objeto JSON que contiene el resultado HTTP y otros metadatos de respuesta.
  • result: la carga JSON devuelta por la llamada HTTP. Se omite si el resultado HTTP recibido es 204 (No Content).

O bien, el @response puede contener un documento XML con el esquema siguiente:

<output>
    <response>
        <status>
            <http code="" description=" " />
        </status>
        <headers>
            <header key="" value="" />
            <header key="" value="" />
        </headers>
    </response>
    <result>
    </result>
</output>

Específicamente:

  • response: un objeto XML que contiene el resultado HTTP y otros metadatos de respuesta.
  • result: la carga XML devuelta por la llamada HTTP. Se omite si el resultado HTTP recibido es 204 (No Content).

En la response sección, aparte del código de estado HTTP y la descripción, se proporcionará todo el conjunto de encabezados de respuesta recibidos en el headers objeto . En el ejemplo siguiente se muestra una response sección en JSON (también la estructura de las respuestas de texto):

"response": {
  "status": {
    "http": {
      "code": 200,
      "description": "OK"
    }
  },
  "headers": {
    "Date": "Thu, 08 Sep 2022 21:51:22 GMT",
    "Content-Length": "1345",
    "Content-Type": "application\/json; charset=utf-8",
    "Server": "Kestrel",
    "Strict-Transport-Security": "max-age=31536000; includeSubDomains"
    }
  }

En el ejemplo siguiente se muestra una response sección en XML:

<response>
    <status>
        <http code="200" description="OK" />
    </status>
    <headers>
        <header key="Date" value="Tue, 01 Apr 1976 21:12:04 GMT" />
        <header key="Content-Length" value="2112" />
        <header key="Content-Type" value="application/xml" />
        <header key="Server" value="Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0" />
        <header key="x-ms-request-id" value="31536000-64bi-64bi-64bi-31536000" />
        <header key="x-ms-version" value="2021-10-04" />
        <header key="x-ms-creation-time" value="Wed, 19 Apr 2023 22:17:33 GMT" />
        <header key="x-ms-server-encrypted" value="true" />
    </headers>
</response>

Puntos de conexión permitidos

Solo se permiten llamadas a puntos de conexión en los siguientes servicios:

Servicio de Azure Dominio
Funciones de Azure *.azurewebsites.net
Servicio App de Azure s *.azurewebsites.net
Azure App Service Environment *.appserviceenvironment.net
Azure Static Web Apps *.azurestaticapps.net
Azure Logic Apps *.logic.azure.com
Azure Event Hubs *.servicebus.windows.net
Azure Event Grid *.eventgrid.azure.net
Azure Cognitive Services *.cognitiveservices.azure.com
Azure OpenAI *.openai.azure.com
PowerApps/Dataverse *.api.crm.dynamics.com
Microsoft Dynamics *.dynamics.com
Azure Container Instances *.azurecontainer.io
Azure Container Apps *.azurecontainerapps.io
Power BI api.powerbi.com
Microsoft Graph graph.microsoft.com
Analysis Services *.asazure.windows.net
IoT Central *.azureiotcentral.com
API Management *.azure-api.net
Azure Blob Storage *.blob.core.windows.net
Azure Files *.file.core.windows.net
Azure Queue Storage *.queue.core.windows.net
Azure Table Storage *.table.core.windows.net
Azure Communication Services *.communications.azure.com
Búsqueda de Bing api.bing.microsoft.com
Azure Key Vault *.vault.azure.net
Azure AI Search *.search.windows.net
Azure Maps *.atlas.microsoft.com
Traductor de Azure AI api.cognitive.microsofttranslator.com

Las reglas de firewall de salida para Azure SQL Database y el mecanismo de control de Azure Synapse Analytics se pueden usar para restringir aún más el acceso saliente a los puntos de conexión externos.

Nota:

Si desea invocar un servicio REST que no esté dentro de la lista de permitidos, puede usar API Management para exponer de forma segura el servicio deseado y hacer que esté disponible para sp_invoke_external_rest_endpoint.

Límites

Tamaño de carga

La carga, tanto cuando se recibe como cuando se envía, se codifica UTF-8 cuando se envía a través de la conexión. En ese formato, su tamaño está limitado a 100 MB.

Longitud de la dirección URL

La longitud máxima de la dirección URL (generada después de usar el parámetro @url y agregar las credenciales especificadas a la cadena de consulta, si existe) es de 8 KB; la longitud máxima de la cadena de consulta (cadena de consulta + cadena de consulta de credenciales) es de 4 KB.

Tamaño de los encabezados

El tamaño máximo de encabezado de solicitud y respuesta (todos los campos de encabezado: encabezados pasados a través de @headers parámetro + encabezado de credencial + encabezados proporcionados por el sistema) es de 8 KB.

Limitaciones

El número de conexiones simultáneas a puntos de conexión externos realizados a través sp_invoke_external_rest_endpoint de se limita al 10 % de los subprocesos de trabajo, con un máximo de 150 trabajos. En una limitación de base de datos única se aplica en el nivel de base de datos, mientras que en una limitación del grupo elástico se aplica tanto en la base de datos como en el nivel de grupo.

Para comprobar cuántas conexiones simultáneas puede mantener una base de datos, ejecute la consulta siguiente:

SELECT
  [database_name],
  DATABASEPROPERTYEX(DB_NAME(), 'ServiceObjective') AS service_level_objective,
  [slo_name] as service_level_objective_long,
  [primary_group_max_outbound_connection_workers] AS max_database_outbound_connection,
  [primary_pool_max_outbound_connection_workers] AS max_pool_outbound_connection
FROM
  sys.dm_user_db_resource_governance
WHERE
  database_id = DB_ID();

Si se prueba una nueva conexión a un punto de conexión externo mediante sp_invoke_external_rest_endpoint cuando ya se alcanzan las conexiones simultáneas máximas, se producirá el error 10928 (o 10936 si ha alcanzado los límites de grupos elásticos). Por ejemplo:

Msg 10928, Level 16, State 4, Procedure sys.sp_invoke_external_rest_endpoint_internal, Line 1 [Batch Start Line 0]
Resource ID : 1. The outbound connections limit for the database is 20 and has been reached.
See 'https://docs.microsoft.com/azure/azure-sql/database/resource-limits-logical-server' for assistance.

Credenciales

Algunos puntos de conexión REST requieren autenticación para poder invocarse correctamente. La autenticación normalmente se puede realizar pasando algunos pares clave-valor específicos en la cadena de consulta o en los encabezados HTTP establecidos con la solicitud.

Es posible usar LAS CREDENCIALES DE ÁMBITO DE BASE DE DATOS para almacenar de forma segura los datos de autenticación (como un token de portador, por ejemplo) que se usarán sp_invoke_external_rest_endpoint para llamar a un punto de conexión protegido. Al crear la CREDENCIAL DE ÁMBITO DE BASE DE DATOS, use el parámetro IDENTITY para especificar qué datos de autenticación se pasarán al punto de conexión invocado y cómo. IDENTITY admite cuatro opciones:

  • HTTPEndpointHeaders: enviar datos de autenticación especificados mediante los encabezados de solicitud
  • HTTPEndpointQueryString: enviar datos de autenticación especificados mediante la cadena de consulta
  • Managed Identity: envíe la identidad administrada asignada por el sistema mediante los encabezados de solicitud.
  • Shared Access Signature: proporciona acceso delegado limitado a los recursos a través de una dirección URL firmada (también denominada SAS).

la CREDENCIAL DE ÁMBITO DE BASE DE DATOS creada se puede usar a través del parámetro @credential :

EXEC sp_invoke_external_rest_endpoint
  @url = N'https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?key1=value1',
  @credential = [https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>]

Con este valor IDENTITY, se agregará database SCOPED CREDENTIAL a los encabezados de solicitud. El par clave-valor que contiene la información de autenticación debe proporcionarse a través del parámetro SECRET mediante un formato JSON plano. Por ejemplo:

CREATE DATABASE SCOPED CREDENTIAL [https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>]
WITH IDENTITY = 'HTTPEndpointHeaders', SECRET = '{"x-functions-key":"<your-function-key-here>"}';

Reglas de nombre de credencial

La CREDENCIAL DE ÁMBITO DE BASE DE DATOS creada debe cumplir con reglas específicas para poder usarse con sp_invoke_external_rest_endpoint. Las reglas son las siguientes:

  • Debe ser una dirección URL válida
  • El dominio de dirección URL debe ser uno de esos dominios incluidos en la lista de permitidos.
  • La dirección URL no debe contener una cadena de consulta.
  • El protocolo + nombre de dominio completo (FQDN) de la dirección URL llamada debe coincidir con el protocolo + FQDN del nombre de credencial.
  • Cada parte de la ruta de acceso url llamada debe coincidir completamente con la parte correspondiente de la ruta de acceso de dirección URL en el nombre de credencial.
  • La credencial debe apuntar a una ruta de acceso más genérica que la dirección URL de la solicitud. Por ejemplo, no se puede usar una credencial creada para la ruta de acceso para la dirección https://northwind.azurewebsite.net/customers URL. https://northwind.azurewebsite.net

Reglas de intercalación y nombre de credencial

RFC 3986 Sección 6.2.2.1 indica que "Cuando un URI usa componentes de la sintaxis genérica, las reglas de equivalencia de sintaxis de componentes siempre se aplican; es decir, que el esquema y el host no distinguen mayúsculas de minúsculas", y el RFC 7230 sección 2.7.3 menciona que "todos los demás se comparan de manera que distingue mayúsculas de minúsculas".

Como hay un conjunto de reglas de intercalación en el nivel de base de datos, se aplicará la siguiente lógica para ser coherente con la regla de intercalación de la base de datos y la RFC mencionada anteriormente. (La regla descrita podría ser más restrictiva que las reglas RFC, por ejemplo, si la base de datos está establecida para usar una intercalación que distingue mayúsculas de minúsculas).

  1. Compruebe si la dirección URL y la credencial coinciden con la RFC, lo que significa:
    • Compruebe el esquema y el host mediante una intercalación que no distingue mayúsculas de minúsculas (Latin1_General_100_CI_AS_KS_WS_SC)
    • Compruebe que todos los demás segmentos de la dirección URL se comparan en una intercalación que distingue mayúsculas de minúsculas (Latin1_General_100_BIN2)
  2. Compruebe que la dirección URL y las credenciales coinciden con las reglas de intercalación de base de datos (y sin realizar ninguna codificación de direcciones URL).

Concesión de permisos para usar credenciales

Los usuarios de base de datos que acceden a una CREDENCIAL DE ÁMBITO DE BASE DE DATOS deben tener permiso para usar esa credencial.

Para usar la credencial, un usuario de base de datos debe tener REFERENCES permiso en una credencial específica:

GRANT REFERENCES ON DATABASE SCOPED CREDENTIAL::[<CREDENTIAL_NAME>] TO [<PRINCIPAL>];

Comentarios

Tipo de espera

Cuando sp_invoke_external_rest_endpoint espere a que se complete la llamada al servicio invocado, notificará un tipo de espera de HTTP_EXTERNAL_CONNECTION.

HTTPS y TLS

Solo se admiten los puntos de conexión configurados para usar HTTPS con al menos el protocolo de cifrado TLS 1.2.

Redireccionamientos HTTP

sp_invoke_external_rest_endpoint no seguirá automáticamente ninguna redirección HTTP recibida como respuesta del punto de conexión invocado.

Encabezados HTTP

sp_invoke_external_rest_endpoint insertará automáticamente los siguientes encabezados en la solicitud HTTP:

  • content-type: establecido en application/json; charset=utf-8
  • accept: establézcalo en application/json
  • user-agent: se establece <EDITION>/<PRODUCT VERSION> por ejemplo: SQL Azure/12.0.2000.8

Aunque el procedimiento almacenado sobrescribirá siempre al agente de usuario, los valores de encabezado content-type y accept se pueden definir por el usuario a través del parámetro @headers . Solo se permite especificar la directiva de tipo multimedia en el tipo de contenido y no es posible especificar las directivas charset o boundary.

Tipos de medios compatibles con la carga de solicitud y respuesta

A continuación se aceptan valores para el tipo de contenido del encabezado.

  • application/json
  • application/vnd.microsoft.*.json
  • aplicación/xml
  • application/vnd.microsoft.*.xml
  • application/vnd.microsoft.*+xml
  • application/x-www-form-urlencoded
  • Mensaje de texto/*

Para el encabezado accept , a continuación se muestran los valores aceptados.

  • application/json
  • aplicación/xml
  • Mensaje de texto/*

Para obtener más información sobre los tipos de encabezado de texto, consulte el registro de tipos de texto en IANA.

Nota:

Si va a probar la invocación del punto de conexión REST con otras herramientas, como cURL o cualquier cliente REST moderno, como Insomnio, asegúrese de incluir los mismos encabezados que se insertan automáticamente para sp_invoke_external_rest_endpoint tener el mismo comportamiento y resultados.

procedimientos recomendados

Uso de una técnica de procesamiento por lotes

Si tiene que enviar un conjunto de filas a un punto de conexión REST, por ejemplo, a una función de Azure o a un centro de eventos, se recomienda procesar por lotes las filas en un único documento JSON, para evitar la sobrecarga de llamadas HTTPS para cada fila enviada. Esto se puede hacer mediante la FOR JSON instrucción , por ejemplo:

-- create the payload
DECLARE @payload AS NVARCHAR(MAX);

SET @payload = (
        SELECT [object_id], [name], [column_id]
        FROM sys.columns
        FOR JSON AUTO
        );

-- invoke the REST endpoint
DECLARE @retcode INT,
    @response AS NVARCHAR(MAX);

EXEC @retcode = sp_invoke_external_rest_endpoint @url = '<REST_endpoint>',
    @payload = @payload,
    @response = @response OUTPUT;

-- return the result
SELECT @retcode, @response;

Ejemplos

Aquí puede encontrar algunos ejemplos sobre cómo usar sp_invoke_external_rest_endpoint para integrarse con servicios comunes de Azure, como Azure Functions o Azure Event Hubs. Puede encontrar más ejemplos para integrar con otros servicios en GitHub.

A Llamada a una función de Azure mediante un enlace de desencadenador HTTP sin autenticación

En el ejemplo siguiente se llama a una función de Azure mediante un enlace de desencadenador HTTP que permite el acceso anónimo.

DECLARE @ret INT, @response NVARCHAR(MAX);

EXEC @ret = sp_invoke_external_rest_endpoint
  @url = N'https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?key1=value1',
  @headers = N'{"header1":"value_a", "header2":"value2", "header1":"value_b"}',
  @payload = N'{"some":{"data":"here"}}',
  @response = @response OUTPUT;

SELECT @ret AS ReturnCode, @response AS Response;

B. Llamada a una función de Azure mediante un enlace de desencadenador HTTP con una clave de autorización

En el ejemplo siguiente se llama a una función de Azure mediante un enlace de desencadenador HTTP configurado para requerir una clave de autorización. La clave de autorización se pasará en el x-function-key encabezado según sea necesario para Azure Functions. Para más información, consulte Autorización de claves de API de Azure Functions.

CREATE DATABASE SCOPED CREDENTIAL [https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>]
WITH IDENTITY = 'HTTPEndpointHeaders', SECRET = '{"x-functions-key":"<your-function-key-here>"}';

DECLARE @ret INT, @response NVARCHAR(MAX);

EXEC @ret = sp_invoke_external_rest_endpoint
  @url = N'https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?key1=value1',
  @headers = N'{"header1":"value_a", "header2":"value2", "header1":"value_b"}',
  @credential = [https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>],
  @payload = N'{"some":{"data":"here"}}',
  @response = @response OUTPUT;

SELECT @ret AS ReturnCode, @response AS Response;

C. Lee el contenido de un archivo de Azure Blob Storage con un token de SAS.

En este ejemplo se lee un archivo de Azure Blob Storage mediante un token de SAS para la autenticación. Los resultados se devolverán en XML, por lo que se necesitará el uso del encabezado "Accept":"application/xml" .

DECLARE @ret INT, @response NVARCHAR(MAX);

EXEC @ret = sp_invoke_external_rest_endpoint
  @url = N'https://blobby.blob.core.windows.net/datafiles/my_favorite_blobs.txt?sp=r&st=2023-07-28T19:56:07Z&se=2023-07-29T03:56:07Z&spr=https&sv=2022-11-02&sr=b&sig=XXXXXX1234XXXXXX6789XXXXX',
  @headers = N'{"Accept":"application/xml"}',
  @method = 'GET',
  @response = @response OUTPUT;

SELECT @ret AS ReturnCode, @response AS Response;

D. Envío de un mensaje a un centro de eventos mediante la identidad administrada de Azure SQL Database

En este ejemplo se muestra cómo puede enviar mensajes a Event Hubs mediante la identidad administrada de Azure SQL. Asegúrese de que ha configurado la identidad administrada del sistema para el servidor lógico de Azure SQL Database que hospeda la base de datos, por ejemplo:

az sql server update -g <resource-group> -n <azure-sql-server> --identity-type SystemAssigned

Después, configure Event Hubs para permitir que la identidad administrada de Azure SQL Server pueda enviar mensajes (rol "Remitente de datos de Azure Event Hubs") al centro de eventos deseado. Para más información, consulte Uso de Event Hubs con identidades administradas.

Una vez hecho esto, puede usar el nombre de Managed Identity identidad al definir la credencial con ámbito de base de datos que usará sp_invoke_external_rest_endpoint. Como se explica en Autenticación de una aplicación con el identificador de Entra de Microsoft para acceder a los recursos de Event Hubs, el nombre del recurso (o identificador) que se usará al usar la autenticación de Microsoft Entra es https://eventhubs.azure.net:

CREATE DATABASE SCOPED CREDENTIAL [https://<EVENT-HUBS-NAME>.servicebus.windows.net]
    WITH IDENTITY = 'Managed Identity',
        SECRET = '{"resourceid": "https://eventhubs.azure.net"}';
GO

DECLARE @Id UNIQUEIDENTIFIER = NEWID();
DECLARE @payload NVARCHAR(MAX) = (
        SELECT *
        FROM (
            VALUES (@Id, 'John', 'Doe')
            ) AS UserTable(UserId, FirstName, LastName)
        FOR JSON AUTO,
            WITHOUT_ARRAY_WRAPPER
        )
DECLARE @url NVARCHAR(4000) = 'https://<EVENT-HUBS-NAME>.servicebus.windows.net/from-sql/messages';
DECLARE @headers NVARCHAR(4000) = N'{"BrokerProperties": "' + STRING_ESCAPE('{"PartitionKey": "' + CAST(@Id AS NVARCHAR(36)) + '"}', 'json') + '"}'
DECLARE @ret INT, @response NVARCHAR(MAX);

EXEC @ret = sp_invoke_external_rest_endpoint @url = @url,
    @headers = @headers,
    @credential = [https://<EVENT-HUBS-NAME>.servicebus.windows.net],
    @payload = @payload,
    @response = @response OUTPUT;

SELECT @ret AS ReturnCode, @response AS Response;

E. Lectura y escritura de un archivo en Azure File Storage con credenciales con ámbito de Azure SQL Database

En este ejemplo se escribe un archivo en una instancia de Azure File Storage mediante credenciales con ámbito de Azure SQL Database para la autenticación y, a continuación, se devuelve el contenido. Los resultados se devolverán en XML, por lo que se necesitará el uso del encabezado "Accept":"application/xml" .

Empiece por crear una clave maestra para Azure SQL Database

create master key encryption by password = '2112templesmlm2BTS21.qwqw!@0dvd'
go

A continuación, cree las credenciales de ámbito de base de datos mediante el token de SAS proporcionado por la cuenta de Azure Blob Storage.

create database scoped credential [filestore]
with identity='SHARED ACCESS SIGNATURE',
secret='sv=2022-11-02&ss=bfqt&srt=sco&sp=seespotrun&se=2023-08-03T02:21:25Z&st=2023-08-02T18:21:25Z&spr=https&sig=WWwwWWwwWWYaKCheeseNXCCCCCCDDDDDSSSSSU%3D'
go

A continuación, cree el archivo y agregue texto a él con las dos instrucciones siguientes:

declare @payload nvarchar(max) = (select * from (values('Hello from Azure SQL!', sysdatetime())) payload([message], [timestamp])for json auto, without_array_wrapper)
declare @response nvarchar(max), @url nvarchar(max), @headers nvarchar(1000);
declare @len int = len(@payload)

-- Create the File
set @url = 'https://myfiles.file.core.windows.net/myfiles/test-me-from-azure-sql.json'
set @headers = json_object(
        'x-ms-type': 'file',
        'x-ms-content-length': cast(@len as varchar(9)),
        'Accept': 'application/xml')
exec sp_invoke_external_rest_endpoint
    @url = @url,
    @method = 'PUT',
    @headers = @headers,
    @credential = [filestore],
    @response = @response output
select cast(@response as xml);

-- Add text to the File
set @headers = json_object(
        'x-ms-range': 'bytes=0-' + cast(@len-1 as varchar(9)),
        'x-ms-write': 'update',
        'Accept': 'application/xml');
set @url = 'https://myfiles.file.core.windows.net/myfiles/test-me-from-azure-sql.json'
set @url += '?comp=range'
exec sp_invoke_external_rest_endpoint
    @url = @url,
    @method = 'PUT',
    @headers = @headers,
    @payload = @payload,
    @credential = [filestore],
    @response = @response output
select cast(@response as xml)
go

Por último, use la siguiente instrucción para leer el archivo.

declare @response nvarchar(max);
declare @url nvarchar(max) = 'https://myfiles.file.core.windows.net/myfiles/test-me-from-azure-sql.json'
exec sp_invoke_external_rest_endpoint
    @url = @url,
    @headers = '{"Accept":"application/xml"}',
    @credential = [filestore],
    @method = 'GET',
    @response = @response output
select cast(@response as xml)
go