{"id":2300,"date":"2023-08-07T04:00:41","date_gmt":"2023-08-07T11:00:41","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/azure-sql\/?p=2300"},"modified":"2023-08-04T15:10:29","modified_gmt":"2023-08-04T22:10:29","slug":"summer-2023-update-for-azure-sql-db-external-rest-endpoint-invocation","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/azure-sql\/summer-2023-update-for-azure-sql-db-external-rest-endpoint-invocation\/","title":{"rendered":"Summer 2023 Update for Azure SQL Database External REST Endpoint Invocation"},"content":{"rendered":"<p><a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1.png\"><img decoding=\"async\" class=\"alignnone size-full wp-image-2302\" src=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1.png\" alt=\"Image sol1\" width=\"3253\" height=\"1804\" srcset=\"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1.png 3253w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1-300x166.png 300w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1-1024x568.png 1024w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1-768x426.png 768w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1-1536x852.png 1536w, https:\/\/devblogs.microsoft.com\/azure-sql\/wp-content\/uploads\/sites\/56\/2023\/08\/sol1-2048x1136.png 2048w\" sizes=\"(max-width: 3253px) 100vw, 3253px\" \/><\/a><\/p>\n<h2>Summer 2023 REST Endpoint Invocation Update<\/h2>\n<p>Welcome to the Summer 2023 REST Endpoint Invocation update post! This summer, we updated the <strong>External REST Endpoints Invocation <\/strong>feature with a few key fixes and additions to help you use more Azure Services with your Azure SQL Database. The feature was<a href=\"https:\/\/devblogs.microsoft.com\/azure-sql\/azure-sql-database-external-rest-endpoints-integration-public-preview\/\"> released to public preview last year<\/a> and this latest set of new features are preparing it for General Availability in the near future.<\/p>\n<p>As a refresher, this feature makes it possible to call REST endpoints from other Azure Services from right in the Azure SQL Database. With a quick call to the system stored procedure <strong><span style=\"font-family: 'courier new', courier, monospace\">sp_invoke_external_rest_endpoint<\/span><\/strong>, you can have data processed via an Azure Function, update a PowerBI dashboard, or even talk to OpenAI. Here is a quick example of sending a REST request to an Azure Function:<\/p>\n<pre>DECLARE @ret INT, @response NVARCHAR(MAX);\r\n\r\nEXEC @ret = sp_invoke_external_rest_endpoint\r\n \u00a0 \u00a0 @url = N'https:\/\/mydemofunction.azurewebsites.net\/api\/HttpTrigger',\r\n \u00a0 \u00a0 @payload = N'{\"name\":\"test\"}',\r\n \u00a0 \u00a0 @method = N'POST',\r\n \u00a0 \u00a0 @response = @response OUTPUT;\r\n\r\nSELECT @ret AS ReturnCode, @response AS Response;<\/pre>\n<p>Very straightforward and easy to use.<\/p>\n<h2>What&#8217;s New for Summer 2023<\/h2>\n<h2>More Azure Services<\/h2>\n<p>To start, we have expanded on the Azure Services you can call, adding OpenAI, Azure Blob Storage, Azure Files, Azure Queue Services and Azure Table Services.<\/p>\n<p>The full list is as follows:<\/p>\n<table class=\"table table-sm\" style=\"width: 99.18%;height: 828px\" aria-label=\"Table 1\">\n<thead>\n<tr style=\"height: 36px\">\n<th style=\"height: 36px;width: 48.1568%\">Azure Service<\/th>\n<th style=\"height: 36px;width: 92.126%\">Domain<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Functions<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azurewebsites.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Apps Service<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azurewebsites.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure App Service Environment<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.appserviceenvironment.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Static Web Apps<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azurestaticapps.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Logic Apps<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.logic.azure.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Event Hubs<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.servicebus.windows.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Event Grid<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.eventgrid.azure.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Cognitive Services<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.cognitiveservices.azure.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">PowerApps \/ Dataverse<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.api.crm.dynamics.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Microsoft Dynamics<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.dynamics.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Container Instances<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azurecontainer.io<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Azure Container Apps<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azurecontainerapps.io<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Power BI<\/td>\n<td style=\"height: 36px;width: 92.126%\">api.powerbi.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Microsoft Graph<\/td>\n<td style=\"height: 36px;width: 92.126%\">graph.microsoft.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">Analysis Services<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.asazure.windows.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">IoT Central<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azureiotcentral.com<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\">API Management<\/td>\n<td style=\"height: 36px;width: 92.126%\">*.azure-api.net<\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\"><strong>Azure OpenAI<\/strong><\/td>\n<td style=\"height: 36px;width: 92.126%\"><strong>*.openai.azure.com<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\"><strong>Azure Blob Storage<\/strong><\/td>\n<td style=\"height: 36px;width: 92.126%\"><strong>*.blob.core.windows.net<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\"><strong>Azure Files<\/strong><\/td>\n<td style=\"height: 36px;width: 92.126%\"><strong>*.file.core.windows.net<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\"><strong>Azure Queue Storage<\/strong><\/td>\n<td style=\"height: 36px;width: 92.126%\"><strong>*.queue.core.windows.net<\/strong><\/td>\n<\/tr>\n<tr style=\"height: 36px\">\n<td style=\"height: 36px;width: 48.1568%\"><strong>Azure Table Storage<\/strong><\/td>\n<td style=\"height: 36px;width: 92.126%\"><strong>*.table.core.windows.net<\/strong><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>XML and Text Payloads<\/h2>\n<p>Expanding on core functionality, we have added the ability to have <span class=\"TextRun SCXW236381207 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW236381207 BCX8\">request and response payloads <\/span><\/span>be text or XML. You can now use the following media types for the header\u00a0<strong><em>content-type:<\/em><\/strong><\/p>\n<ul>\n<li>application\/json<\/li>\n<li>application\/vnd.microsoft.*.json<\/li>\n<li>application\/xml<\/li>\n<li>application\/vnd.microsoft.*.xml<\/li>\n<li>application\/vnd.microsoft.*+xml<\/li>\n<li>application\/x-www-form-urlencoded<\/li>\n<li>text\/*<\/li>\n<\/ul>\n<p>and the for the\u00a0<strong><em>accept<\/em>\u00a0<\/strong>header, the following are now the accepted values:<\/p>\n<ul>\n<li>application\/json<\/li>\n<li>application\/xml<\/li>\n<li>text\/*<\/li>\n<\/ul>\n<p>To illustrate this, if we take the example from above where we called an Azure Function, we can alter the parameters passed to the stored procedure by adding a header:<\/p>\n<pre>\"Accept\":\"text\/*\"<\/pre>\n<p>This tells the procedure to expect a text response back from the Azure Function. The full call would look like the following:<\/p>\n<div>\n<pre>declare @url nvarchar(4000) = N'https:\/\/texttest1.azurewebsites.net\/api\/HttpTrigger1?';\r\nDECLARE @headers nvarchar(102) = N'{<strong>\"Accept\":\"text\/*\"<\/strong>}'\r\ndeclare @payload nvarchar(max) = N'{\"name\":\"Frank\"}'\r\ndeclare @ret int, @response nvarchar(max);\r\nexec @ret = sp_invoke_external_rest_endpoint\r\n  \u00a0 @url = @url,\r\n  \u00a0 @method = 'POST',\r\n  \u00a0 @headers = @headers,\r\n  \u00a0 @payload = @payload,\r\n  \u00a0 @response = @response output;\r\n  \u00a0\r\nselect @ret as ReturnCode, @response as Response;<\/pre>\n<\/div>\n<p>And text returning in a payload will look similar to the following example:<\/p>\n<div>\n<div>{<\/div>\n<pre>\u00a0 \u00a0 \"response\": {\r\n  \u00a0 \u00a0 \u00a0 \"status\": {\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"http\": {\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"code\": 200,\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"description\": \"OK\"\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 }\r\n  \u00a0 \u00a0 \u00a0 },\r\n  \u00a0 \u00a0 \u00a0 \"headers\": {\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"Date\": \"Fri, 04 Aug 2023 16:54:11 GMT\",\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"Transfer-Encoding\": \"chunked\",\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"Content-Type\": \"text\\\/plain; charset=utf-8\",\r\n  \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \"Request-Context\": \"appId=cid-v1:2112-3d3c-141976-8a1b-goatch33s3\"\r\n  \u00a0 \u00a0 \u00a0 }\r\n  \u00a0 },\r\n  \u00a0 \"result\": \"Hello, Frank. This HTTP triggered function executed successfully. Oh, this is text as well!\"\r\n}<\/pre>\n<\/div>\n<p>Moving to XML, return responses using XML will look like the following:<\/p>\n<pre><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">output<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003&lt;<span class=\"hljs-name\">response<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003&lt;<span class=\"hljs-name\">status<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003\u2003&lt;<span class=\"hljs-name\">http<\/span> <span class=\"hljs-attr\">code<\/span>=<span class=\"hljs-string\">\"\"<\/span> <span class=\"hljs-attr\">description<\/span>=<span class=\"hljs-string\">\" \"<\/span> \/&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003&lt;\/<span class=\"hljs-name\">status<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003&lt;<span class=\"hljs-name\">headers<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003\u2003&lt;<span class=\"hljs-name\">header<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">\"\"<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"\"<\/span> \/&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003\u2003&lt;<span class=\"hljs-name\">header<\/span> <span class=\"hljs-attr\">key<\/span>=<span class=\"hljs-string\">\"\"<\/span> <span class=\"hljs-attr\">value<\/span>=<span class=\"hljs-string\">\"\"<\/span> \/&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003\u2003&lt;\/<span class=\"hljs-name\">headers<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003&lt;\/<span class=\"hljs-name\">response<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003&lt;<span class=\"hljs-name\">result<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">\u2003&lt;\/<span class=\"hljs-name\">result<\/span>&gt;\r\n<\/span><span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">output<\/span>&gt;<\/span><\/pre>\n<p>Like the text accept header, XML is done in the same manner:<\/p>\n<p><code class=\"lang-sql\" data-author-content=\"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 \"><span class=\"hljs-string\">'Accept'<\/span>: <span class=\"hljs-string\">'application\/xml'<\/span><\/code><\/p>\n<p>with the following code example highlighting this:<\/p>\n<div>\n<pre>DECLARE @ret INT, @response NVARCHAR(MAX);\r\nEXEC @ret = sp_invoke_external_rest_endpoint\r\n  @url = N'https:\/\/blobby.blob.core.windows.net\/datafiles\/my_favorite_blobs.txt?sp=r&amp;st=2023&amp;se=2023&amp;spr=https&amp;sv=2022&amp;sr=b&amp;sig=XXXXXX',\r\n  @headers = N'{\"Accept\":\"application\/xml\"}',\r\n  @method = 'GET',\r\n  @response = @response OUTPUT;\r\nSELECT cast(@response as xml);\r\ngo<\/pre>\n<div>with the response being:<\/div>\n<\/div>\n<div><\/div>\n<div>\n<pre>&lt;output&gt;\r\n\u2003\u2003&lt;response&gt;\r\n\u2003\u2003\u2003\u2003&lt;status&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;http code=\"200\" description=\"OK\" \/&gt;\r\n\u2003\u2003\u2003\u2003&lt;\/status&gt;\r\n\u2003\u2003\u2003\u2003&lt;headers&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Date\" value=\"Fri, 04 Aug 2023 18:46:11 GMT\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Content-Length\" value=\"2297\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Content-Type\" value=\"application\/xml\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Content-MD5\" value=\"l+LknBXHtvd1gwMsBKFWXw==\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Last-Modified\" value=\"Wed, 19 Apr 2023 22:17:33 GMT\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Accept-Ranges\" value=\"bytes\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Server\" value=\"Windows-Azure-Blob\/1.0 Microsoft-HTTPAPI\/2.0\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"x-ms-version\" value=\"2021-10-04\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"x-ms-creation-time\" value=\"Wed, 19 Apr 2023 22:17:33 GMT\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"x-ms-lease-status\" value=\"unlocked\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"x-ms-lease-state\" value=\"available\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"x-ms-blob-type\" value=\"BlockBlob\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"Content-Disposition\" value=\"\" \/&gt;\r\n\u2003\u2003\u2003\u2003\u2003\u2003&lt;header key=\"x-ms-server-encrypted\" value=\"true\" \/&gt;\r\n\u2003\u2003\u2003\u2003&lt;\/headers&gt;\r\n\u2003\u2003&lt;\/response&gt;\r\n\u2003\u2003&lt;result&gt;Lorem ipsum dolor sit amet, consectetur adipiscing elit<span style=\"font-size: 1rem;text-align: var(--bs-body-text-align)\">&lt;\/result&gt;\r\n&lt;\/output&gt;<\/span><\/pre>\n<\/div>\n<div><\/div>\n<h2>More Examples!<\/h2>\n<h3>OpenAI<\/h3>\n<p>The first example is calling OpenAI in Azure and asking it a deep philosophical question that only AI could answer:<\/p>\n<pre>declare @url nvarchar(4000) = N'https:\/\/demo.openai.azure.com\/openai\/deployments\/chat\/completions';\r\ndeclare @headers nvarchar(102) = N'{\"api-key\":\u201cXXXXXXXXXXXXXX\"}'\r\ndeclare @payload nvarchar(max) = N'{\"messages\":[{\"role\":\"system\",\"content\":\"Why is the sky blue?\"}]}'\r\ndeclare @ret int, @response nvarchar(max); \r\n\r\nexec @ret = sp_invoke_external_rest_endpoint\r\n \u00a0 \u00a0 @url = @url,\r\n \u00a0 \u00a0 @method = 'POST',\r\n \u00a0 \u00a0 @headers = @headers,\r\n \u00a0 \u00a0 @payload = @payload,\r\n \u00a0 \u00a0 @timeout = 230,\r\n \u00a0 \u00a0 @response = @response output; \u00a0 \u00a0  \r\n\r\nselect @ret as ReturnCode, @response as Response;<\/pre>\n<p>With our answer being:<\/p>\n<pre>\"The blue color of the sky is due to the scattering of sunlight by the gas molecules and\r\ntiny particles in the Earth's atmosphere, primarily nitrogen and oxygen. These molecules\r\nabsorb and scatter light in different ways, with blue light being scattered more than\r\nother colors because it has a shorter wavelength. This scattering of blue light in all\r\ndirections makes the sky appear blue to our eyes. At sunrise and sunset, when the light\r\nmust travel through more of the Earth's atmosphere, the sky can \r\nappear red or orange due to the scattering of longer wavelengths of light.\"<\/pre>\n<p>Very deep indeed!<\/p>\n<h3>Azure Files and more XML<\/h3>\n<p>Next, let&#8217;s look at an example of calling Azure Files and the new XML functionality. In this example, we will create some database scoped credentials using a SAS token from Azure Blob Storage, create a file, put some text into it, and finally read the file back. (this example is <a href=\"https:\/\/learn.microsoft.com\/sql\/relational-databases\/system-stored-procedures\/sp-invoke-external-rest-endpoint-transact-sql?view=azuresqldb-current&amp;tabs=request-headers\">in the docs<\/a> as well)<\/p>\n<p>Start by creating a master key for the Azure SQL Database if one has not already been created:<\/p>\n<pre class=\"has-inner-focus\">create master key encryption by password = '2112templesmlm2BTS21.qwqw!@0dvd'\r\ngo<\/pre>\n<p>Then, create the database scoped credentials using the SAS token provided by the Azure Blob Storage Account.<\/p>\n<pre>create database scoped credential [filestore]\r\nwith identity='SHARED ACCESS SIGNATURE', \r\nsecret='sv=2022-11-02&amp;ss=bfqt&amp;srt=sco&amp;sp=seespotrun&amp;se=2023-08-03T02:21:25Z&amp;st=2023-08-02T18:21:25Z&amp;spr=https&amp;sig=WWwwWWwwWWYaKCheeseNXCCCCCCDDDDDSSSSSU%3D'\r\ngo<\/pre>\n<p>Next, create the file and add text to it with the following two statements:<\/p>\n<pre class=\"has-inner-focus\" role=\"group\" aria-label=\"Horizontally scrollable code\"><code class=\"lang-sql\" data-author-content=\"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 \"><span class=\"hljs-keyword\">\r\ndeclare<\/span> @payload <span class=\"hljs-keyword\">nvarchar<\/span>(<span class=\"hljs-keyword\">max<\/span>) = (<span class=\"hljs-keyword\">select<\/span> * <span class=\"hljs-keyword\">from<\/span> (<span class=\"hljs-keyword\">values<\/span>(<span class=\"hljs-string\">'Hello from Azure SQL!'<\/span>, sysdatetime())) payload([message], [<span class=\"hljs-built_in\">timestamp<\/span>])<span class=\"hljs-keyword\">for<\/span> <span class=\"hljs-keyword\">json<\/span> <span class=\"hljs-keyword\">auto<\/span>, without_array_wrapper)\r\n<span class=\"hljs-keyword\">declare<\/span> @response <span class=\"hljs-keyword\">nvarchar<\/span>(<span class=\"hljs-keyword\">max<\/span>), @<span class=\"hljs-keyword\">url<\/span> <span class=\"hljs-keyword\">nvarchar<\/span>(<span class=\"hljs-keyword\">max<\/span>), @headers <span class=\"hljs-keyword\">nvarchar<\/span>(<span class=\"hljs-number\">1000<\/span>);\r\n<span class=\"hljs-keyword\">declare<\/span> @<span class=\"hljs-keyword\">len<\/span> <span class=\"hljs-built_in\">int<\/span> = <span class=\"hljs-keyword\">len<\/span>(@payload)\r\n\r\n<span class=\"hljs-comment\">-- Create the File<\/span>\r\n<span class=\"hljs-keyword\">set<\/span> @<span class=\"hljs-keyword\">url<\/span> = <span class=\"hljs-string\">'https:\/\/myfiles.file.core.windows.net\/myfiles\/test-me-from-azure-sql.json'<\/span>\r\n<span class=\"hljs-keyword\">set<\/span> @headers = json_object(\r\n        <span class=\"hljs-string\">'x-ms-type'<\/span>: <span class=\"hljs-string\">'file'<\/span>,\r\n        <span class=\"hljs-string\">'x-ms-content-length'<\/span>: <span class=\"hljs-keyword\">cast<\/span>(@<span class=\"hljs-keyword\">len<\/span> <span class=\"hljs-keyword\">as<\/span> <span class=\"hljs-built_in\">varchar<\/span>(<span class=\"hljs-number\">9<\/span>)),\r\n        <span class=\"hljs-string\">'Accept'<\/span>: <span class=\"hljs-string\">'application\/xml'<\/span>)\r\nexec sp_invoke_external_rest_endpoint\r\n    @<span class=\"hljs-keyword\">url<\/span> = @<span class=\"hljs-keyword\">url<\/span>,\r\n    @method = <span class=\"hljs-string\">'PUT'<\/span>,\r\n    @headers = @headers,\r\n    @credential = [filestore],\r\n    @response = @response <span class=\"hljs-keyword\">output<\/span>\r\n<span class=\"hljs-keyword\">select<\/span> <span class=\"hljs-keyword\">cast<\/span>(@response <span class=\"hljs-keyword\">as<\/span> <span class=\"hljs-keyword\">xml<\/span>);\r\n\r\n<span class=\"hljs-comment\">-- Add text to the File<\/span>\r\n<span class=\"hljs-keyword\">set<\/span> @headers = json_object(\r\n        <span class=\"hljs-string\">'x-ms-range'<\/span>: <span class=\"hljs-string\">'bytes=0-'<\/span> + <span class=\"hljs-keyword\">cast<\/span>(@<span class=\"hljs-keyword\">len<\/span><span class=\"hljs-number\">-1<\/span> <span class=\"hljs-keyword\">as<\/span> <span class=\"hljs-built_in\">varchar<\/span>(<span class=\"hljs-number\">9<\/span>)),\r\n        <span class=\"hljs-string\">'x-ms-write'<\/span>: <span class=\"hljs-string\">'update'<\/span>,\r\n        <span class=\"hljs-string\">'Accept'<\/span>: <span class=\"hljs-string\">'application\/xml'<\/span>);\r\n<span class=\"hljs-keyword\">set<\/span> @<span class=\"hljs-keyword\">url<\/span> = <span class=\"hljs-string\">'https:\/\/myfiles.file.core.windows.net\/myfiles\/test-me-from-azure-sql.json'<\/span>\r\n<span class=\"hljs-keyword\">set<\/span> @<span class=\"hljs-keyword\">url<\/span> += <span class=\"hljs-string\">'?comp=range'<\/span>\r\nexec sp_invoke_external_rest_endpoint\r\n    @<span class=\"hljs-keyword\">url<\/span> = @<span class=\"hljs-keyword\">url<\/span>,\r\n    @method = <span class=\"hljs-string\">'PUT'<\/span>,\r\n    @headers = @headers,\r\n    @payload = @payload,\r\n    @credential = [filestore],\r\n    @response = @response <span class=\"hljs-keyword\">output<\/span>\r\n<span class=\"hljs-keyword\">select<\/span> <span class=\"hljs-keyword\">cast<\/span>(@response <span class=\"hljs-keyword\">as<\/span> <span class=\"hljs-keyword\">xml<\/span>)\r\n<span class=\"hljs-keyword\">go<\/span>\r\n<\/code><\/pre>\n<p>Finally, use the following statement to read the file<\/p>\n<div id=\"code-try-22\" class=\"codeHeader\" data-bi-name=\"code-header\">\n<div class=\"successful-copy-alert position-absolute right-0 top-0 left-0 bottom-0 display-flex align-items-center justify-content-center has-text-success-invert has-background-success is-transparent\" aria-hidden=\"true\"><\/div>\n<\/div>\n<pre class=\"has-inner-focus\"><code class=\"lang-sql\" data-author-content=\"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 = '{&quot;Accept&quot;:&quot;application\/xml&quot;}', @credential = [filestore], @method = 'GET', @response = @response output select cast(@response as xml) go \"><span class=\"hljs-keyword\">\r\ndeclare<\/span> @response <span class=\"hljs-keyword\">nvarchar<\/span>(<span class=\"hljs-keyword\">max<\/span>);\r\n<span class=\"hljs-keyword\">declare<\/span> @<span class=\"hljs-keyword\">url<\/span> <span class=\"hljs-keyword\">nvarchar<\/span>(<span class=\"hljs-keyword\">max<\/span>) = <span class=\"hljs-string\">'https:\/\/myfiles.file.core.windows.net\/myfiles\/test-me-from-azure-sql.json'<\/span>\r\nexec sp_invoke_external_rest_endpoint\r\n    @<span class=\"hljs-keyword\">url<\/span> = @<span class=\"hljs-keyword\">url<\/span>,\r\n    @headers = <span class=\"hljs-string\">'{\"Accept\":\"application\/xml\"}'<\/span>,\r\n    @credential = [filestore],\r\n    @method = <span class=\"hljs-string\">'GET'<\/span>,\r\n    @response = @response <span class=\"hljs-keyword\">output<\/span>\r\n<span class=\"hljs-keyword\">select<\/span> <span class=\"hljs-keyword\">cast<\/span>(@response <span class=\"hljs-keyword\">as<\/span> <span class=\"hljs-keyword\">xml<\/span>)\r\n<span class=\"hljs-keyword\">go<\/span><\/code><\/pre>\n<h2>What&#8217;s Next?<\/h2>\n<p>In the coming months, we hope to add some more Azure Services to the Allow list as well as move out of public preview and into General Availability. Stay tuned!<\/p>\n<h2>For More Information<\/h2>\n<p>To learn more about <code class=\" prettyprinted\"><span class=\"pln\">sp_invoke_external_rest_endpoint<\/span><\/code>, look at the documentation: <a href=\"https:\/\/learn.microsoft.com\/en-us\/sql\/relational-databases\/system-stored-procedures\/sp-invoke-external-rest-endpoint-transact-sql?view=azuresqldb-current\" target=\"_blank\" rel=\"noopener\">sp_invoke_external_rest_endpoint (Transact-SQL) (Preview).<\/a><\/p>\n<p>Want more examples? You can use this GitHub Repository here: <a href=\"https:\/\/github.com\/Azure-Samples\/azure-sql-db-invoke-external-rest-endpoints\" target=\"_blank\" rel=\"noopener\">azure-sql-db-invoke-external-rest-endpoints.<\/a><\/p>\n<p>Finally, and very importantly, let us know if you like this feature and how you are using it.\u00a0 <b>Use the comment section below to give us your feedback and to tell us how you\u2019d like to see this feature evolving or drop us a line and contact us directly!<\/b>\u00a0If you have some specific request, make sure to add it to the\u00a0<a href=\"https:\/\/feedback.azure.com\/d365community\/forum\/04fe6ee0-3b25-ec11-b6e6-000d3a4f0da0\" target=\"_blank\" rel=\"noopener\">Azure SQL and SQL Server feedback portal<\/a>, so that other users can contribute and help us prioritize future development.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summer 2023 REST Endpoint Invocation Update Welcome to the Summer 2023 REST Endpoint Invocation update post! This summer, we updated the External REST Endpoints Invocation feature with a few key fixes and additions to help you use more Azure Services with your Azure SQL Database. The feature was released to public preview last year and [&hellip;]<\/p>\n","protected":false},"author":95874,"featured_media":2143,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[555,1,576,577],"tags":[244,510,541,465,469,30,435,29,410,433,34,578],"class_list":["post-2300","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-functions","category-azure-sql","category-rest","category-rest-endpoint-invocation","tag-net","tag-azure-sql-database","tag-azure-functions","tag-azuresql","tag-azuresqldb","tag-developers","tag-functions","tag-json","tag-rest","tag-serverless","tag-t-sql","tag-xml"],"acf":[],"blog_post_summary":"<p>Summer 2023 REST Endpoint Invocation Update Welcome to the Summer 2023 REST Endpoint Invocation update post! This summer, we updated the External REST Endpoints Invocation feature with a few key fixes and additions to help you use more Azure Services with your Azure SQL Database. The feature was released to public preview last year and [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/2300","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/users\/95874"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/comments?post=2300"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/posts\/2300\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media\/2143"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/media?parent=2300"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/categories?post=2300"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/azure-sql\/wp-json\/wp\/v2\/tags?post=2300"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}