<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>linked server Archives | ZappySys Blog</title>
	<atom:link href="https://zappysys.com/blog/tag/linked-server/feed/" rel="self" type="application/rss+xml" />
	<link>https://zappysys.com/blog/tag/linked-server/</link>
	<description>SSIS / ODBC Drivers / API Connectors for JSON, XML, Azure, Amazon AWS, Salesforce, MongoDB and more</description>
	<lastBuildDate>Wed, 11 Mar 2026 07:08:29 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.4.4</generator>

<image>
	<url>https://zappysys.com/blog/wp-content/uploads/2023/01/cropped-zappysys-symbol-large-32x32.png</url>
	<title>linked server Archives | ZappySys Blog</title>
	<link>https://zappysys.com/blog/tag/linked-server/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Import Azure Blob files into SQL Server (CSV/JSON/XML Driver)</title>
		<link>https://zappysys.com/blog/import-azure-blob-files-sql-server-csv-json-xml-driver/</link>
		
		<dc:creator><![CDATA[ZappySys]]></dc:creator>
		<pubDate>Wed, 07 Aug 2019 15:52:30 +0000</pubDate>
				<category><![CDATA[Azure Blob CSV Driver]]></category>
		<category><![CDATA[Azure Blob JSON Driver]]></category>
		<category><![CDATA[Azure Blob XML Driver]]></category>
		<category><![CDATA[ODBC Drivers]]></category>
		<category><![CDATA[ODBC Gateway]]></category>
		<category><![CDATA[ODBC PowerPack]]></category>
		<category><![CDATA[azure]]></category>
		<category><![CDATA[blob]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[linked server]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[xml]]></category>
		<guid isPermaLink="false">https://zappysys.com/blog/?p=7638</guid>

					<description><![CDATA[<p>Introduction There might be a case when you have many CSV, JSON or XML files in Azure Blob and you want them to be imported straight into a SQL Server table. Here come ZappySys ODBC PowerPack and ZappySys Data Gateway (part of ODBC PowerPack) which will enable you to accomplish that. ZappySys ODBC PowerPack includes powerful Azure [&#8230;]</p>
<p>The post <a href="https://zappysys.com/blog/import-azure-blob-files-sql-server-csv-json-xml-driver/">Import Azure Blob files into SQL Server (CSV/JSON/XML Driver)</a> appeared first on <a href="https://zappysys.com/blog">ZappySys Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Introduction</h2>
<p style="text-align: justify;"><img loading="lazy" decoding="async" class="alignnone wp-image-7639 size-thumbnail alignleft" src="https://zappysys.com/blog/wp-content/uploads/2019/08/blob-to-sql-150x150.png" alt="" width="150" height="150" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/blob-to-sql-150x150.png 150w, https://zappysys.com/blog/wp-content/uploads/2019/08/blob-to-sql-300x300.png 300w, https://zappysys.com/blog/wp-content/uploads/2019/08/blob-to-sql.png 400w" sizes="(max-width: 150px) 100vw, 150px" />There might be a case when you have many CSV, JSON or XML files in Azure Blob and you want them to be imported straight into a SQL Server table. Here come <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> and <a href="https://zappysys.com/products/odbc-powerpack/data-gateway/" target="_blank" rel="noopener">ZappySys Data Gateway</a> (part of ODBC PowerPack) which will enable you to accomplish that. ZappySys ODBC PowerPack includes powerful Azure Blob CSV, Azure Blob JSON and Azure Blob XML drivers that let you connect to an Azure Storage Explorer and read the contents from the files in the Container. Bringing in ZappySys Data Gateway allows doing that right from a SQL Server. Let&#8217;s begin and see how to Import Azure Blob files into SQL Server (CSV/JSON/XML Driver).</p>
<p>These drivers are related to this article:</p>
<div class="content_block" id="custom_post_widget-7641"><div style="display: table-row; background: #f7f7f7;">
<div style="display: table-cell; padding: 1em; border: 1px solid #ccc;"><img loading="lazy" decoding="async" style="vertical-align: middle; width: 50px; height: 50px; max-width: 50px;" src="//zappysys.com/images/odbc-powerpack/odbc-azure-blob-csv-driver.png" alt="Azure Blob CSV Driver" width="50" height="50" /></div>
<div style="display: table-cell; padding: 1em; border: 1px solid #ccc; border-left: none; width: 100%;"><a href="//zappysys.com/products/odbc-powerpack/azure-blob-odbc-driver-csv-files/" target="_blank" rel="noopener">Azure Blob Driver (for CSV Files)</a></div>
</div></div>
<div class="content_block" id="custom_post_widget-7643"><div style="display: table-row; background: #f7f7f7;">
<div style="display: table-cell; padding: 1em; border: 1px solid #ccc;"><img loading="lazy" decoding="async" style="vertical-align: middle; width: 50px; height: 50px; max-width: 50px;" src="https://zappysys.com/images/odbc-powerpack/odbc-azure-blob-json-driver.png" alt="Azure Blob JSON Driver" width="50" height="50" /></div>
<div style="display: table-cell; padding: 1em; border: 1px solid #ccc; border-left: none; width: 100%;"><a href="//zappysys.com/products/odbc-powerpack/azure-blob-odbc-driver-json-files/" target="_blank" rel="noopener">Azure Blob Driver (for JSON Files)</a></div>
</div></div>
<div class="content_block" id="custom_post_widget-7645"><div style="display: table-row; background: #f7f7f7;">
<div style="display: table-cell; padding: 1em; border: 1px solid #ccc;"><img loading="lazy" decoding="async" style="vertical-align: middle; width: 50px; height: 50px; max-width: 50px;" src="//zappysys.com/images/odbc-powerpack/odbc-azure-blob-xml-driver.png" alt="Azure Blob XML Driver" width="50" height="50" /></div>
<div style="display: table-cell; padding: 1em; border: 1px solid #ccc; border-left: none; width: 100%;"><a href="//zappysys.com/products/odbc-powerpack/azure-blob-odbc-driver-xml-files/" target="_blank" rel="noopener">Azure Blob Driver (for XML Files)</a></div>
</div></div>
<h2>Prerequisites</h2>
<ol>
<li>Firstly, Download and install <a href="https://go.microsoft.com/fwlink/?LinkId=717179&amp;clcid=0x4009" target="_blank" rel="noopener">Microsoft Azure Storage Emulator</a> and <a href="https://azure.microsoft.com/en-us/features/storage-explorer/" target="_blank" rel="noopener">Microsoft Azure Storage Explorer.</a></li>
<li>SQL Server instance installed (can be a <a href="https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/sql-server-2016-express-localdb" target="_blank" rel="noopener">SQL Server Express LocalDB</a> instance).</li>
<li><a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms" target="_blank" rel="noopener">SQL Server Management Studio</a> (SSMS) installed.</li>
<li><a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> installed (must be installed on a Windows machine; can be a different machine than SQL Server is installed on).</li>
</ol>
<p><strong>NOTE:</strong> If you want to use Live account (Azure Storage) then you can skip Step #3</p>
<h2>Getting started</h2>
<p>In order to start, we will show several examples. ZappySys includes Data Gateway that will help you in reading data of Azure Blob files. Here we are showing you is, how to Import Azure Blob files into SQL Server (CSV/JSON/XML Driver).</p>
<p>You can connect to Azure Storage Service from SSIS, you will need Storage Account Name and Access Key. Ask your SysAdmin or responsible person to provide that information to you. <a href="https://zappysys.com/forums/topic/azure-blob-storage-how-to-create-new-storage-account-and-get-access-key/" target="_blank" rel="noopener">Click here</a> to read more about how to get your Storage Account Name and Access Key. Here are sample Credentials.</p><pre class="crayon-plain-tag">Account Name: mystorageaccount
Access Key: Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==</pre><p>
If you don&#8217;t have Azure Storage account then you can try offline mode on your local machine. You can just <a href="http://www.microsoft.com/en-us/download/details.aspx?id=42317" target="_blank" rel="noopener">download Azure Storage Emulator</a> and start testing.</p>
<h2><span id="Setup_Azure_Storage_client_tools_and_Create_Queue"><span id="Setup_Azure_Storage_client_tools">Setup Azure Storage Explorer</span></span></h2>
<p>Setup Azure Storage client tools we will start from a simple example of how to load Invoice Data from a CSV that is located in Azure Blob, then we will load JSON contacts data from them and finally, we will proceed by loading contacts from many XML files those are compressed in ZIP.</p>
<ol>
<li>Once you have <a href="https://go.microsoft.com/fwlink/?LinkId=717179&amp;clcid=0x4009" target="_blank" rel="noopener">downloaded and installed storage emulator</a> You can launch Microsoft Azure Storage Emulator from its Physical location or from the desktop or start menu shortcut.
<div id="attachment_3631" class="wp-caption aligncenter">
<p><a href="https://i1.wp.com/zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-location.png?ssl=1" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="wp-image-3631 size-full" src="https://i1.wp.com/zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-location.png?resize=720%2C79&amp;ssl=1" alt="Azure Storage Emulator Physical Location" width="643" height="70" srcset="https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-location.png 859w, https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-location-300x33.png 300w, https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-location-768x84.png 768w" sizes="(max-width: 643px) 100vw, 643px" /></a></p>
<p class="wp-caption-text">Azure Storage Emulator Physical Location</p>
</div>
</li>
<li>If you can see the below-attached Command Prompt screen after Emulator started. Then you can proceed to start Microsoft Azure Storage Explorer as the Azure Storage Emulator is started successfully.
<div id="attachment_3633" class="wp-caption aligncenter">
<p><a href="https://i2.wp.com/zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-screen-after-started-e1552723801433.png?ssl=1" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="wp-image-3633 size-full" src="https://i2.wp.com/zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-emulator-screen-after-started-e1552723801433.png?resize=700%2C237&amp;ssl=1" alt="Command Prompt Screen after Microsoft Azure Storage Emulator Started" width="643" height="218" /></a></p>
<p class="wp-caption-text">Command Prompt Screen after Microsoft Azure Storage Emulator Started</p>
</div>
</li>
<li>Now, you have to <a href="https://azure.microsoft.com/en-us/features/storage-explorer/" target="_blank" rel="noopener">download and install Microsoft Azure Storage Explorer</a> and then you can launch Microsoft Azure Storage Explorer from its Physical location or from the desktop or start menu shortcut.
<div id="attachment_3635" class="wp-caption aligncenter">
<p><a href="https://i0.wp.com/zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-location.png?ssl=1" target="_blank" rel="noopener"><img loading="lazy" decoding="async" class="wp-image-3635 size-full" src="https://i0.wp.com/zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-location.png?resize=720%2C84&amp;ssl=1" alt="Microsoft Azure Storage Explorer Location" width="643" height="75" srcset="https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-location.png 827w, https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-location-300x35.png 300w, https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-location-768x90.png 768w" sizes="(max-width: 643px) 100vw, 643px" /></a></p>
<p class="wp-caption-text">Microsoft Azure Storage Explorer Location.</p>
</div>
</li>
<li>For Creating a Blob Container, First of all, you need to go to Microsoft Storage Explorer Window. Then you can go through like this way (Storage Accounts –&gt; (Development) –&gt; Blob Containers).
<div id="attachment_3637" style="width: 556px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-create-blob-container-e1552723740747.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3637" class="size-full wp-image-3637" src="https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-create-blob-container-e1552723740747.png" alt="Microsoft Azure Storage Explorer : Create Blob Container" width="546" height="584" srcset="https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-create-blob-container-e1552723740747.png 546w, https://zappysys.com/blog/wp-content/uploads/2018/04/microsoft-azure-storage-explorer-create-blob-container-e1552723740747-280x300.png 280w" sizes="(max-width: 546px) 100vw, 546px" /></a><p id="caption-attachment-3637" class="wp-caption-text">Microsoft Azure Storage Explorer: Create a Blob Container</p></div></li>
</ol>
<h2><span style="font-size: 14pt;">Open and Configure ZappySys Data Gateway</span></h2>
<div class="content_block" id="custom_post_widget-7369">Now let's look at steps to configure Data Gateway after installation:
<ol>
 	<li>Assuming you have installed <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> using default options (Which also enables Data Gateway Service)</li>
 	<li>Search "Gateway" in your start menu and click ZappySys Data Gateway
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/start-menu-open-zappysys-data-gateway.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/start-menu-open-zappysys-data-gateway.png" alt="Open ZappySys Data Gateway" /></a>
<p class="wp-caption-text">Open ZappySys Data Gateway</p>

</div></li>
 	<li>First make sure Gateway Service is running (Verify Start icon is disabled)</li>
 	<li>Also verify Port on General Tab
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/ZappySys-data-gateway-port-5000.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/03/ZappySys-data-gateway-port-5000.png" alt="Port Number setting on ZappySys Data Gateway" /></a>
<p class="wp-caption-text">Port Number setting on ZappySys Data Gateway</p>

</div></li>
 	<li>Now go to Users tab. <strong>Click Add</strong> icon to add a new user. Check Is admin to give access to all data sources you add in future. If you don't check admin then you have to manually configure user permission for each data source.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/zappysys-data-gateway-add-user.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/zappysys-data-gateway-add-user.png" alt="Add Data Gateway User" /></a>
<p class="wp-caption-text">Add Data Gateway User</p>

</div></li>
</ol>
&nbsp;</div>
<h2>Import CSV file located at Azure Blob into SQL Server</h2>
<h3>Overview</h3>
<p>Let&#8217;s say you have CSV file that is located in Azure Blob Container, and you want them all data into your SQL Server. We will follow the same steps for that we will do for import JSON and XML file into SQL Server.</p>
<div id="attachment_7719" style="width: 612px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-file-list.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7719" class="wp-image-7719 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-file-list.png" alt="Azure Blob Container - CSV File Located" width="602" height="418" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-file-list.png 602w, https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-file-list-300x208.png 300w" sizes="(max-width: 602px) 100vw, 602px" /></a><p id="caption-attachment-7719" class="wp-caption-text">Azure Blob Container &#8211; CSV File Located</p></div>
<h3>Create an Azure Blob CSV data source in ZappySys Data Gateway</h3>
<ol>
<li>The first thing you will have to do is to create a data source in ZappySys Data Gateway. In the Data Source tab, Just click on <strong>Add</strong> button, give the data source a name, e.g. &#8220;<strong>MyInvoiceCSV</strong>&#8220;, and then select <strong>Native &#8211; ZappySys Azure Blob CSV Driver</strong><strong>.</strong>
<div id="attachment_7746" style="width: 572px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-data-source-e1565697707852.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7746" class="wp-image-7746 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-data-source-e1565697707852.png" alt="Create Data Source - Azure Blob CSV Driver" width="562" height="539" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-data-source-e1565697707852.png 562w, https://zappysys.com/blog/wp-content/uploads/2019/08/azure-blob-csv-data-source-e1565697707852-300x288.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></a><p id="caption-attachment-7746" class="wp-caption-text">Create Data Source &#8211; Azure Blob CSV Driver</p></div></li>
<li>Then click on <strong>Edit</strong> and add the Data Gateway user you created in the <strong>Users</strong> tab. We will use this user later when adding a Linked Server to the Data Gateway to authenticate:<img loading="lazy" decoding="async" class="size-full wp-image-7864 aligncenter" src="https://zappysys.com/blog/wp-content/uploads/2019/08/import-csv-from-azure-blob-storage-to-sql-server-add-user.png" alt="" width="681" height="629" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/import-csv-from-azure-blob-storage-to-sql-server-add-user.png 681w, https://zappysys.com/blog/wp-content/uploads/2019/08/import-csv-from-azure-blob-storage-to-sql-server-add-user-300x277.png 300w" sizes="(max-width: 681px) 100vw, 681px" /></li>
<li>Now, click on the Edit button to configure &#8220;<strong>MyInvoiceCSV</strong>&#8221; Azure Blob CSV Data Source.
<div id="attachment_7722" style="width: 572px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/edit-azure-blob-csv-data-source.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7722" class="wp-image-7722 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/edit-azure-blob-csv-data-source.png" alt="Configure Data Gateway" width="562" height="539" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/edit-azure-blob-csv-data-source.png 562w, https://zappysys.com/blog/wp-content/uploads/2019/08/edit-azure-blob-csv-data-source-300x288.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></a><p id="caption-attachment-7722" class="wp-caption-text">Configure Data Gateway</p></div></li>
<li>When a window open, click on <strong>Click here to Configure the Connection</strong> and select Use the Microsoft Azure Storage Emulator. If you have Online <em>Storage Account</em> and <em><em>Account Key </em></em>then Select Enter Storage Account Credentials and enter it.<em><em><br />
</em></em></p>
<div style="width: 503px" class="wp-caption aligncenter"><a href="https://zappysys.com/onlinehelp/odbc-powerpack/scr/images/azure-blob-json-driver/azure-blob-json-driver-create-connection.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" src="https://zappysys.com/onlinehelp/odbc-powerpack/scr/images/azure-blob-json-driver/azure-blob-json-driver-create-connection.png" alt="Create Azure Storage Connection" width="493" height="499" /></a><p class="wp-caption-text">Create Azure Storage Connection</p></div></li>
<li>Now, Select Azure Blob Container and file from it and In the Data Format / Compression (Zip / GZip) tab set suitable file Compression Format (Zip or GZip).
<div id="attachment_7721" style="width: 753px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/configure-azure-blob-csv-data-source.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7721" class="wp-image-7721 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/configure-azure-blob-csv-data-source.png" alt="ZappySys Azure Blob CSV - Configure Driver" width="743" height="623" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/configure-azure-blob-csv-data-source.png 743w, https://zappysys.com/blog/wp-content/uploads/2019/08/configure-azure-blob-csv-data-source-300x252.png 300w" sizes="(max-width: 743px) 100vw, 743px" /></a><p id="caption-attachment-7721" class="wp-caption-text">ZappySys Azure Blob CSV &#8211; Configure Driver</p></div></li>
<li>Go to the <strong>Preview</strong> tab and click on the <strong>Preview Data</strong> button to make sure everything is configured correctly and preview the results.
<div id="attachment_7726" style="width: 753px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/preview-azure-blob-csv-data-source.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7726" class="wp-image-7726 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/preview-azure-blob-csv-data-source.png" alt="ZappySys Azure Blob CSV - Preview Data" width="743" height="570" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/preview-azure-blob-csv-data-source.png 743w, https://zappysys.com/blog/wp-content/uploads/2019/08/preview-azure-blob-csv-data-source-300x230.png 300w" sizes="(max-width: 743px) 100vw, 743px" /></a><p id="caption-attachment-7726" class="wp-caption-text">ZappySys Azure Blob CSV &#8211; Preview Data</p></div></li>
<li>Now, Click on OK button also Save and Restart Service.
<div id="attachment_7724" style="width: 572px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/save-and-restart-service-data-source.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7724" class="wp-image-7724 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/save-and-restart-service-data-source.png" alt="ZappySys Data Gateway Service - Save and Restart" width="562" height="539" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/save-and-restart-service-data-source.png 562w, https://zappysys.com/blog/wp-content/uploads/2019/08/save-and-restart-service-data-source-300x288.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></a><p id="caption-attachment-7724" class="wp-caption-text">ZappySys Data Gateway Service &#8211; Save and Restart</p></div></li>
<li>That&#8217;s all, now we are ready to proceed and add a Linked Server to this data source.</li>
</ol>
<h3 id="Set-up-a-SQL-Server-Linked-Server">Set up a SQL Server Linked Server</h3>
<div class="content_block" id="custom_post_widget-5432">Once you configured the data source in Gateway, we can now set up a Linked Server in a SQL Server.
<ol style="margin-left: 10px;">
 	<li>Open SSMS and connect to a SQL Server.</li>
 	<li>Go to Root &gt; Server Objects &gt; Linked Servers node. Right click and click <strong>New Linked Server...
</strong>
<div class="wp-caption alignnone">
<a href="https://zappysys.com/blog/wp-content/uploads/2018/03/create-new-linked-server-ssms.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/03/create-new-linked-server-ssms.png" alt="Add Linked Server in SQL Server" />
</a>
<p class="wp-caption-text">Adding Linked Server in SQL Server</p>

</div></li>
 	<li>Now enter the linked server name, select Provider as SQL Native Client.</li>
 	<li>Enter data source as <strong><span class="lang:default decode:true crayon-inline">GatewayServerName,PORT_NUMBER</span></strong> where server name is where ZappySys Gateway is running (can be the same as SQL Server machine or a remote machine). Default PORT_NUMBER is 5000 but confirm that on the Gateway &gt; General tab in case it's different.</li>
 	<li>Enter Catalog Name. This must match name from Data gateway Data sources grid &gt; Name column
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/ssms-sql-server-configure-linked-server-2.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/ssms-sql-server-configure-linked-server-2.png" alt="Configure Linked Server Provider, Catalog, Server, Port for ZappySys Data Gateway Connection" />
</a>
<p class="wp-caption-text">Configure Linked Server Provider, Catalog, Server, Port for ZappySys Data Gateway Connection</p>
</div>
<div style="color: #31708f;background-color: #d9edf7;border-color: #bce8f1;padding: 15px;margin-bottom: 20px;border: 1px solid transparent;border-radius: 4px;">
<strong>INFO:</strong><br/>
<ul>
    <li>
      For <strong>SQL Server 2012, 2014, 2016, 2017, and 2019</strong>, use the <em>SQL Server Native Client 11.0</em> as the Provider.
    </li>
    <li>
      For <strong>SQL Server 2022 or higher</strong>, use the <em>Microsoft OLE DB Driver for SQL Server</em> as the Provider.
    </li>
  </ul>
</div></li>
 	<li>Click on Security Tab and select the last option "<strong>Be made using this security context</strong>". Enter your gateway user account here.
<div class="wp-caption alignnone">
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-5456" src="https://zappysys.com/blog/wp-content/uploads/2018/11/add-linked-server-sql-server-3-security-2.png" alt="" width="690" height="625" srcset="https://zappysys.com/blog/wp-content/uploads/2018/11/add-linked-server-sql-server-3-security-2.png 690w, https://zappysys.com/blog/wp-content/uploads/2018/11/add-linked-server-sql-server-3-security-2-300x272.png 300w" sizes="(max-width: 690px) 100vw, 690px" />
<p class="wp-caption-text">Configuring Linked Server credentials</p>
</li>
<li>
        <p>Optional: Under the Server Options Tab, Enable <b>RPC</b> and <b>RPC Out</b> and Disable Promotion of Distributed Transactions<b>(MSDTC)</b>.</p>
		<div class="wp-caption alignnone">
			<img decoding="async" class="block margin-bottom-10 img-thumbnail" src="https://zappysys.com/blog/wp-content/uploads/2018/11/linked-server-options-rpc-msdtc.png" title="RPC and MSDTC Settings" alt="RPC and MSDTC Settings" />
			<p class="wp-caption-text">RPC and MSDTC Settings</p>
		</div>
        <hr />
        <p>
            You need to enable RPC Out if you plan to use <b><i>EXEC(...) AT [MY_LINKED_SERVER_NAME]</i></b> rather than OPENQUERY.
            <br />
            If don't enabled it, you will encounter the <i>'Server "MY_LINKED_SERVER_NAME" is not configured for RPC'</i> error.
        </p>
        <p>
            Query Example:
            <code class="sql">EXEC('Select * from Products') AT [MY_LINKED_SERVER_NAME]</code>
        </p>
        <hr />
        <p>
            If you plan to use <b><i>'INSERT INTO...EXEC(....) AT [MY_LINKED_SERVER_NAME]'</i></b> in that case you need to Disable Promotion of Distributed Transactions(MSDTC).
            <br />
            If don't disabled it, you will encounter the <i>'The operation could not be performed because OLE DB provider "SQLNCLI11/MSOLEDBSQL" for linked server "MY_LINKED_SERVER_NAME" was unable to begin a distributed transaction.'</i> error.
        </p>
        <p>
            Query Example:
<pre class="">Insert Into dbo.Products 
EXEC('Select * from Products') AT [MY_LINKED_SERVER_NAME]</pre>
        </p>
        <hr />
</li>
 	<li>Click OK to save the Linked Server.</li>
</ol></div>
<h3>Execute the SQL query</h3>
<p>Once again, if you created the Linked Server with name &#8220;GATEWAY&#8221;, execute this SQL query in SSMS:</p>
<p><code>SELECT * INTO MyInvoices FROM OPENQUERY([GATEWAY], 'SELECT * FROM $')<br />
SELECT * FROM MyInvoices</code></p>
<h3>The results</h3>
<p>You should see a similar view, once you execute the query:</p>
<div id="attachment_7862" style="width: 713px" class="wp-caption alignnone"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7862" class="wp-image-7862 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/80-import-csv-from-azure-blob-storage-into-sql-server-the-results-data-is-loaded-into-sql-server.png" alt="The results of loading many CSVs from Azure Blob into SQL Server" width="703" height="441" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/80-import-csv-from-azure-blob-storage-into-sql-server-the-results-data-is-loaded-into-sql-server.png 703w, https://zappysys.com/blog/wp-content/uploads/2019/08/80-import-csv-from-azure-blob-storage-into-sql-server-the-results-data-is-loaded-into-sql-server-300x188.png 300w" sizes="(max-width: 703px) 100vw, 703px" /><p id="caption-attachment-7862" class="wp-caption-text">The results of loading many CSVs from Azure Blob into SQL Server</p></div>
<h2>Import JSON file located at Azure Blob into SQL Server</h2>
<h3>Overview</h3>
<p>Let&#8217;s say you have JSON file that is located in Azure Blob Container, and you want them all data into your SQL Server. We will follow the same steps of the import CSV file into SQL Server and we will do for XML file into SQL Server.</p>
<h3>Create an Azure Blob JSON data source in ZappySys Data Gateway</h3>
<p>Follow the steps as in Create an Azure Blob CSV data source in ZappySys Data Gateway section when adding a new data source, except for these two steps:</p>
<ol>
<li>The first thing you will have to do is to create a data source in ZappySys Data Gateway. Just click <strong>Add</strong> button, give the data source a name, e.g. &#8220;<strong>MyContactsJSON</strong>&#8220;, and then select <strong>Native &#8211; ZappySys Azure Blob JSON Driver.</strong>
<div id="attachment_7663" style="width: 637px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/10-create-new-data-source-in-data-gateway-to-load-json-files-from-azure-blob-into-sql-server-1.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7663" class="wp-image-7663 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/10-create-new-data-source-in-data-gateway-to-load-json-files-from-azure-blob-into-sql-server-1.png" alt="ZappySys Data Gateway - Create New Data Source" width="627" height="583" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/10-create-new-data-source-in-data-gateway-to-load-json-files-from-azure-blob-into-sql-server-1.png 627w, https://zappysys.com/blog/wp-content/uploads/2019/08/10-create-new-data-source-in-data-gateway-to-load-json-files-from-azure-blob-into-sql-server-1-300x279.png 300w" sizes="(max-width: 627px) 100vw, 627px" /></a><p id="caption-attachment-7663" class="wp-caption-text">ZappySys Data Gateway &#8211; Create New Data Source</p></div>
<div class="mceTemp"></div>
<div class="mceTemp"></div>
</li>
<li>After that, select a JSON file from container you want to load, and then click <strong>Select Filter</strong> button to choose data you want to be displayed in SQL Server.
<div id="attachment_7670" style="width: 667px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/40-configure-azure-blob-json-data-source-to-load-data-into-sql-server-1.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7670" class="wp-image-7670 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/40-configure-azure-blob-json-data-source-to-load-data-into-sql-server-1.png" alt="Configuring the JSON data source to load a JSON from Azure Blob container into SQL Server" width="657" height="702" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/40-configure-azure-blob-json-data-source-to-load-data-into-sql-server-1.png 657w, https://zappysys.com/blog/wp-content/uploads/2019/08/40-configure-azure-blob-json-data-source-to-load-data-into-sql-server-1-281x300.png 281w" sizes="(max-width: 657px) 100vw, 657px" /></a><p id="caption-attachment-7670" class="wp-caption-text">Configuring the JSON data source to load a JSON from Azure Blob container into SQL Server</p></div></li>
</ol>
<p>Now you are ready to create a Linked Server and connect to the data source you just created. If you used &#8220;<strong>MyContactsJSON</strong>&#8221; as the data source name, make sure to use the same name when creating a Linked Server.</p>
<h3>Set up a SQL Server Linked Server</h3>
<p>Again, follow the very same steps from the section above where we <a href="#Set-up-a-SQL-Server-Linked-Server">added the Linked Server to a CSV data source</a>, except that change <em>Catalog</em> property of the Linked Server to match the name of the Azure Blob JSON data source we created. Once you do that, you are ready to load JSON into your SQL Server.</p>
<h3>Execute the SQL query</h3>
<p style="text-align: justify;">Once you created the Linked Server to ZappySys Data Gateway, you are ready to execute the SQL query and load data into SQL Server. Supposedly, you created the Linked Server with the name &#8220;GATEWAY&#8221;, then open SSMS and execute the following query:</p>
<p><code>SELECT * INTO MyContacts FROM openquery([GATEWAY], 'SELECT * FROM $')<br />
SELECT * FROM MyContacts</code></p>
<h3>The results</h3>
<p>You should see similar results after you execute the query:</p>
<div id="attachment_7536" style="width: 609px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/06/600-the-results-of-importing-amazon-s3-data-into-sql-server-using-json-driver.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7536" class="wp-image-7536 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/06/600-the-results-of-importing-amazon-s3-data-into-sql-server-using-json-driver.png" alt="The results of getting JSON data straight from Azure Blob JSON" width="599" height="257" srcset="https://zappysys.com/blog/wp-content/uploads/2019/06/600-the-results-of-importing-amazon-s3-data-into-sql-server-using-json-driver.png 599w, https://zappysys.com/blog/wp-content/uploads/2019/06/600-the-results-of-importing-amazon-s3-data-into-sql-server-using-json-driver-300x129.png 300w" sizes="(max-width: 599px) 100vw, 599px" /></a><p id="caption-attachment-7536" class="wp-caption-text">The results of getting JSON data straight from Azure Blob JSON</p></div>
<p>Now we are ready to proceed to the next section and import many XML files at once.</p>
<h2>Import many XML files located at Azure Blob into SQL Server</h2>
<h3>Overview</h3>
<p>Supposedly, you have many XMLs where each one is zipped and you want to load them all into a SQL Server table.</p>
<div id="attachment_7675" style="width: 616px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/65-load-many-compressed-xml-files-from-azure-blob-container-into-sql-server.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7675" class="wp-image-7675 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/65-load-many-compressed-xml-files-from-azure-blob-container-into-sql-server.png" alt="Zipped XML files located in Azure Blob container to be loaded into SQL Server" width="606" height="415" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/65-load-many-compressed-xml-files-from-azure-blob-container-into-sql-server.png 606w, https://zappysys.com/blog/wp-content/uploads/2019/08/65-load-many-compressed-xml-files-from-azure-blob-container-into-sql-server-300x205.png 300w" sizes="(max-width: 606px) 100vw, 606px" /></a><p id="caption-attachment-7675" class="wp-caption-text">Zipped XML files located in Azure Blob container to be loaded into SQL Server</p></div>
<p>The first thing you will have to do is to create a data source, based on ZappySys Azure Blob XML Driver. Let&#8217;s proceed and just do that.</p>
<h3>Create an Azure Blob XML data source in ZappySys Data Gateway</h3>
<p>Follow the same steps as in Create an Azure Blob JSON data source in ZappySys Data Gateway section when adding a new data source, except for these two steps:</p>
<ol>
<li>When adding a data source select <strong>Native &#8211; ZappySys Azure Blob XML Driver</strong> as <em>Connector Type.</em>
<div id="attachment_7674" style="width: 430px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/67-create-new-azure-blob-xml-data-source-in-data-gateway-to-load-xml-files-into-sql-selver.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7674" class="wp-image-7674 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/67-create-new-azure-blob-xml-data-source-in-data-gateway-to-load-xml-files-into-sql-selver.png" alt="Choosing &quot;ZappySys Azure Blob XML Driver&quot; to load XMLs to SQL Server" width="420" height="296" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/67-create-new-azure-blob-xml-data-source-in-data-gateway-to-load-xml-files-into-sql-selver.png 420w, https://zappysys.com/blog/wp-content/uploads/2019/08/67-create-new-azure-blob-xml-data-source-in-data-gateway-to-load-xml-files-into-sql-selver-300x211.png 300w" sizes="(max-width: 420px) 100vw, 420px" /></a><p id="caption-attachment-7674" class="wp-caption-text">Choosing &#8220;ZappySys Azure Blob XML Driver&#8221; to load XMLs to SQL Server</p></div>
<div class="mceTemp"></div>
</li>
<li>Then click on <strong>Edit</strong> and select Azure Blob Container and file from it and In the Data Format / Compression (Zip / GZip) tab set suitable file Compression Format (Zip or GZip).
<div id="attachment_7673" style="width: 667px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/08/70-configure-azure-blob-xml-data-source-to-load-into-sql-server.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7673" class="wp-image-7673 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/08/70-configure-azure-blob-xml-data-source-to-load-into-sql-server.png" alt="Configuring data source based on ZappySys Azure Blob XML Driver to load XMLs into SQL Server" width="657" height="515" srcset="https://zappysys.com/blog/wp-content/uploads/2019/08/70-configure-azure-blob-xml-data-source-to-load-into-sql-server.png 657w, https://zappysys.com/blog/wp-content/uploads/2019/08/70-configure-azure-blob-xml-data-source-to-load-into-sql-server-300x235.png 300w" sizes="(max-width: 657px) 100vw, 657px" /></a><p id="caption-attachment-7673" class="wp-caption-text">Configuring data source based on ZappySys Azure Blob XML Driver to load XMLs into SQL Server</p></div></li>
<li>Now we are ready to set up a Linked Server to this newly created data source.</li>
</ol>
<h3>Set up a SQL Server Linked Server</h3>
<p style="text-align: justify;">Follow the very same steps from the section above where we <a href="#Set-up-a-SQL-Server-Linked-Server">added the Linked Server to a CSV data source</a>, except that change <em>Catalog</em> property of the Linked Server to match the name of the Azure Blob XML data source you created. Once you do that, you are ready to load XMLs into your SQL Server.</p>
<h3>Execute the SQL query</h3>
<p>Again, if you created the Linked Server with name &#8220;GATEWAY&#8221;, execute the following SQL query in SSMS:</p>
<p><code>SELECT * INTO MyContacts FROM openquery([GATEWAY], 'SELECT * FROM $')<br />
SELECT * FROM MyContacts</code></p>
<h3>The results</h3>
<p>You should see a similar view once you execute the query:</p>
<div id="attachment_7550" style="width: 614px" class="wp-caption aligncenter"><a href="https://zappysys.com/blog/wp-content/uploads/2019/06/750-the-result-of-importing-xml-data-from-amazon-s3-into-sql-server.png" target="_blank" rel="noopener"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7550" class="wp-image-7550 size-full" src="https://zappysys.com/blog/wp-content/uploads/2019/06/750-the-result-of-importing-xml-data-from-amazon-s3-into-sql-server.png" alt="The data of many XMLs loaded from Azure Blob Container into SQL Server" width="604" height="360" srcset="https://zappysys.com/blog/wp-content/uploads/2019/06/750-the-result-of-importing-xml-data-from-amazon-s3-into-sql-server.png 604w, https://zappysys.com/blog/wp-content/uploads/2019/06/750-the-result-of-importing-xml-data-from-amazon-s3-into-sql-server-300x179.png 300w" sizes="(max-width: 604px) 100vw, 604px" /></a><p id="caption-attachment-7550" class="wp-caption-text">The data of many XMLs loaded from Azure Blob Container into SQL Server</p></div>
<p>Now we are ready to move to the next section and recursively scan CSVs and load them into SQL Server.</p>
<h2>Conclusion</h2>
<p style="text-align: justify;">We had a goal to import Azure Blob files into SQL Server from SQL Server itself. We learned how to Import Azure Blob files into SQL Server (CSV/JSON/XML Driver), which some of them were zipped and were located at different folders and subfolders. It was possible to accomplish that using <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ODBC PowerPack</a>, <a href="https://zappysys.com/products/odbc-powerpack/data-gateway/" target="_blank" rel="noopener">ZappySys Data Gateway</a>, and ODBC PowerPack drivers &#8211; Azure Blob JSON Driver, Azure Blob XML Driver, and Azure Blob CSV Driver. At first, we created data sources in the Data Gateway, then we created Linked Servers in SQL Server and connected to ZappySys Data Gateway, which finally made it possible to load data from Azure Blob straight from SQL queries in SSMS.</p>
<h2>References</h2>
<p>Finally, you can use the following links for more information:</p>
<ul>
<li><a href="https://zappysys.com/onlinehelp/odbc-powerpack/scr/azure-blob-csv-odbc-driver-intro.htm" target="_blank" rel="noopener">Azure Blob CSV Driver</a></li>
<li><a href="https://zappysys.com/onlinehelp/odbc-powerpack/scr/azure-blob-json-odbc-driver-intro.htm" target="_blank" rel="noopener">Azure Blob JSON Driver</a></li>
<li><a href="https://zappysys.com/onlinehelp/odbc-powerpack/scr/azure-blob-xml-odbc-driver-intro.htm" target="_blank" rel="noopener">Azure Blob XML Driver</a></li>
</ul>
<p>The post <a href="https://zappysys.com/blog/import-azure-blob-files-sql-server-csv-json-xml-driver/">Import Azure Blob files into SQL Server (CSV/JSON/XML Driver)</a> appeared first on <a href="https://zappysys.com/blog">ZappySys Blog</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to import Amazon MWS data into SQL Server (T-SQL)</title>
		<link>https://zappysys.com/blog/import-amazon-mws-data-sql-server-t-sql/</link>
		
		<dc:creator><![CDATA[ZappySys]]></dc:creator>
		<pubDate>Thu, 30 May 2019 15:37:37 +0000</pubDate>
				<category><![CDATA[CSV File / REST API Driver]]></category>
		<category><![CDATA[ODBC Gateway]]></category>
		<category><![CDATA[T-SQL (SQL Server)]]></category>
		<category><![CDATA[XML File / SOAP API Driver]]></category>
		<category><![CDATA[Amazon MWS]]></category>
		<category><![CDATA[linked server]]></category>
		<category><![CDATA[openquery]]></category>
		<category><![CDATA[t-sql]]></category>
		<guid isPermaLink="false">https://zappysys.com/blog/?p=6961</guid>

					<description><![CDATA[<p>Introduction In our previous blog post we saw how to import rest API in SQL Server. Using same concepts lets look at how to import Amazon MWS Data into SQL Server. We will explore many techniques to call Amazon MWS API and learn how to automate Amazon MWS data extraction without doing any ETL. We [&#8230;]</p>
<p>The post <a href="https://zappysys.com/blog/import-amazon-mws-data-sql-server-t-sql/">How to import Amazon MWS data into SQL Server (T-SQL)</a> appeared first on <a href="https://zappysys.com/blog">ZappySys Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Introduction</h2>
<div class="su-note"  style="border-color:#e2dec9;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#fcf8e3;border-color:#ffffff;color:#8a6d3b;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;">
<strong><span style="vertical-align: text-bottom;font-size: 0.86em;">⚠️</span> Deprecation Notice: MWS API is deprecated</strong><br />
Amazon&#8217;s MWS (Marketplace Web Service) is being deprecated and <strong>replaced by the newer AWS Selling Partner API (SP-API).</strong> For a more robust and secure integration, we <strong>recommend</strong> using our <strong><a href="/api/integration-hub/amazon-selling-partner-connector/">AWS Selling Partner (SP-API) Connector</a>.</strong> As Amazon is phasing out MWS functionality and eventually plans to fully deprecate it.<br />
</div></div>
<p><a href="https://zappysys.com/blog/wp-content/uploads/2016/10/amazon-mws-api-integration.png"><img loading="lazy" decoding="async" class="wp-image-1632 alignleft" src="https://zappysys.com/blog/wp-content/uploads/2016/10/amazon-mws-api-integration.png" alt="" width="98" height="98" srcset="https://zappysys.com/blog/wp-content/uploads/2016/10/amazon-mws-api-integration.png 505w, https://zappysys.com/blog/wp-content/uploads/2016/10/amazon-mws-api-integration-150x150.png 150w, https://zappysys.com/blog/wp-content/uploads/2016/10/amazon-mws-api-integration-300x300.png 300w" sizes="(max-width: 98px) 100vw, 98px" /></a>In our previous blog post we saw how to <a href="https://zappysys.com/blog/import-rest-api-json-sql-server/" target="_blank" rel="noopener">import rest API in SQL Server</a>. Using same concepts lets look at how to import Amazon MWS Data into SQL Server. We will explore many techniques to call Amazon MWS API and learn how to automate Amazon MWS data extraction without doing any ETL. We will call MWS XML or CSV API just using T-SQL code. We will also learn how to Download Reports from by calling MWS API.</p>
<p>You can also refer other articles <a href="https://zappysys.com/blog/import-amazon-mws-data-power-bi/" target="_blank" rel="noopener">here (Power BI)</a> and <a href="https://zappysys.com/blog/call-amazon-mws-api-using-ssis-marketplace-web-service/" target="_blank" rel="noopener">here (SSIS)</a></p>
<p>&nbsp;</p>
<div class="content_block" id="custom_post_widget-7048"><h2>Requirements</h2>
This article talks about few tools and techniques in order to load API data in SQL Server. Please make sure following prerequisites are met.
<ol>
 	<li>Download and Install <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> (This includes XML / JSON / REST API and few other drivers for SQL Server and ODBC connectivity in tools like Excel, Power BI, SSRS)</li>
 	<li>Make sure you have access to SQL Server Instance. If you cant find one still want to try what is mentioned in this article then install <a href="https://www.microsoft.com/en-us/sql-server/sql-server-editions-express" target="_blank" rel="noopener">FREE SQL Express Edition</a></li>
 	<li>Confirm that you have SSMS Installed. If you don't have then you can download <a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms?view=sql-server-2017">from here</a>.</li>
</ol></div>
<h2></h2>
<h2>About Amazon MWS  API</h2>
<p>If you want to sell something on Amazon you can use their e-commerce platform with some monthly fee. You can setup your entire online store / inventory using admin interface.</p>
<p>Amazon Marketplace Web Service (Amazon MWS) is an integrated web service API that helps Amazon sellers to programmatically exchange data on listings, orders, payments, reports, and more. Using these API you can read or write data from your Seller account and integrate it inside your own Systems (e.g. Reporting / ETL / BI tools).</p>
<div class="su-note"  style="border-color:#e5de9d;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#fff8b7;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;">NOTE: Amazon MWS may allow only certain number of requests per minute depending which API you calling so you might want to use each call wisely. We will suggest you various techniques throughout this article so you can avoid errors so read each section carefully. You can find Throttling information on API help page itself (<a href="https://docs.developer.amazonservices.com/en_IT/orders-2013-09-01/Orders_ListOrders.html" target="_blank" rel="noopener">like this one</a> see throttling section. Also <a href="https://docs.developer.amazonservices.com/en_IT/dev_guide/DG_Throttling.html">this one</a>).</div></div>
<h2>Obtain MWS API Access Key / Secret and Seller ID</h2>
<p>Very first thing to call any MWS API is to obtain Access Key, Secret Key and Seller ID (i.e. Merchant ID). To obtain this you first have to <a href="https://docs.developer.amazonservices.com/en_US/dev_guide/DG_Registering.html" target="_blank" rel="noopener">register a developer</a>.</p>
<p>Here is where to look for your Merchant ID and Key / Secret.  Here is direct link to <a href="https://sellercentral.amazon.com/gp/account-manager/home.html/ref=xx_userperms_dnav_userperms" target="_blank" rel="noopener">User Permissions</a> page.</p>
<div id="attachment_4843" style="width: 997px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/09/obtain-amazon-mws-developer-aws-access-key-secret-key-sellerid.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-4843" class="size-full wp-image-4843" src="https://zappysys.com/blog/wp-content/uploads/2018/09/obtain-amazon-mws-developer-aws-access-key-secret-key-sellerid.png" alt="How to get Amazon MWS developer keys and know your Merchant ID (i.e. Seller ID)" width="987" height="422" srcset="https://zappysys.com/blog/wp-content/uploads/2018/09/obtain-amazon-mws-developer-aws-access-key-secret-key-sellerid.png 987w, https://zappysys.com/blog/wp-content/uploads/2018/09/obtain-amazon-mws-developer-aws-access-key-secret-key-sellerid-300x128.png 300w, https://zappysys.com/blog/wp-content/uploads/2018/09/obtain-amazon-mws-developer-aws-access-key-secret-key-sellerid-768x328.png 768w" sizes="(max-width: 987px) 100vw, 987px" /></a><p id="caption-attachment-4843" class="wp-caption-text">How to get Amazon MWS developer keys and know your Merchant ID (i.e. Seller ID)</p></div>
<h2>Getting Started</h2>
<p>Now let&#8217;s look at step by step instructions on how to call Amazon MWS API and then import into Power BI. In below steps we will use  <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> so make sure it&#8217;s installed first.</p>
<h3>Using ScratchPad to Test Amazon MWS API</h3>
<p>Each MWS API has set of required and optional parameters. You can refer each API page for details. For example <a href="https://docs.developer.amazonservices.com/en_US/products/Products_ListMatchingProducts.html" target="_blank" rel="noopener">ListMatchingProducts</a> API which we will use as an example. To make MWS API testing / learning easy, Amazon provides online testing tool called <a href="https://mws.amazonservices.com/scratchpad/index.html" target="_blank" rel="noopener">MWS ScratchPad</a>. We will use this tool to craft API requests and use that information in ODBC driver SQL queries and later import data in Power BI.</p>
<ol>
<li>Open <a href="https://mws.amazonservices.com/scratchpad/index.html" target="_blank" rel="noopener">MWS ScratchPad</a>  by vising <strong>https://mws.amazonservices.com/scratchpad/index.html</strong></li>
<li>Select <strong>Products</strong> API category and pick <strong>ListMatchingProducts</strong> API</li>
<li>Enter your <strong>SellerID</strong> (i.e. Merchant ID), Developer AccessKey (i.e. <strong>AWSAccessKeyId</strong>) and <strong>Secret Key</strong> we obtained in the previous section. Enter MarketId (e.g. <strong>ATVPDKIKX0DER</strong> for USA Market) and other parameters as below and Click Submit to see response.
<div id="attachment_4844" style="width: 800px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-scratchpad-online-testing-tool.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-4844" class="size-full wp-image-4844" src="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-scratchpad-online-testing-tool.png" alt="Using Amazon MWS ScratchPad (API Testing Tool - Created by Amazon)" width="790" height="500" srcset="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-scratchpad-online-testing-tool.png 790w, https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-scratchpad-online-testing-tool-300x190.png 300w, https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-scratchpad-online-testing-tool-768x486.png 768w" sizes="(max-width: 790px) 100vw, 790px" /></a><p id="caption-attachment-4844" class="wp-caption-text">Using Amazon MWS ScratchPad (API Testing Tool &#8211; Created by Amazon)</p></div></li>
<li>Click on the <strong>Response Details</strong> Tab to extract some important information we will use for ODBC configuration. Notice attributes in red rectangles. They are the ones which we will need in the POST request Body. ZappySys Drivers supply many common parameters automatically but any API endpoint specific parameter must be supplied in the Request Body. For example you dont have to supply <b>SignatureVersion, Timestamp, Signature or SignatureMethod</b>
<div id="attachment_4847" style="width: 933px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-response-scratchpad-listmatchingproducts-example.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-4847" class="size-full wp-image-4847" src="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-response-scratchpad-listmatchingproducts-example.png" alt="Calling Amazon MWS API in Scratchpad Testing Tool (Response Details Tab) - ListMatchingProducts Example" width="923" height="527" srcset="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-response-scratchpad-listmatchingproducts-example.png 923w, https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-response-scratchpad-listmatchingproducts-example-300x171.png 300w, https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-response-scratchpad-listmatchingproducts-example-768x439.png 768w" sizes="(max-width: 923px) 100vw, 923px" /></a><p id="caption-attachment-4847" class="wp-caption-text">Calling Amazon MWS API in Scratchpad Testing Tool (Response Details Tab) &#8211; ListMatchingProducts Example</p></div></li>
</ol>
<p>This API requires Market ID parameter so enter it as per your Market where you selling. For example USA marketplaceid = ATVPDKIKX0DER. You can lookup correct MarketplaceId by <a href="https://docs.developer.amazonservices.com/en_US/dev_guide/DG_Endpoints.html" target="_blank" rel="noopener">checking this help (endpoints / marketplaces)</a>.</p>
<h3></h3>
<h2>Setup Amazon MWS API Connections</h2>
<div class="content_block" id="custom_post_widget-5411"><h3><span style="font-size: 14pt;">Configure ZappySys Data Gateway</span></h3>
Now let's look at steps to configure Data Gateway after installation.
<ol style="margin-left: 0;">
 	<li style="text-align: left;">Assuming you have installed <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> using default options (Which also enables Data Gateway Service)</li>
 	<li style="text-align: left;">Search "Gateway" in your start menu and click ZappySys Data Gateway
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/start-menu-open-zappysys-data-gateway.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/start-menu-open-zappysys-data-gateway.png" alt="Open ZappySys Data Gateway" /></a>
<p class="wp-caption-text">Opening ZappySys Data Gateway</p>

</div></li>
 	<li>First, make sure Gateway Service is running (Verify Start icon is disabled)</li>
 	<li>Also, verify Port on General Tab
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/ZappySys-data-gateway-port-5000.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/03/ZappySys-data-gateway-port-5000.png" alt="Port Number setting on ZappySys Data Gateway" /></a>
<p class="wp-caption-text">Checking port number setting on ZappySys Data Gateway</p>

</div></li>
 	<li>Now go to Users tab. <strong>Click Add</strong> icon to add a new user. Check Is admin to give access to all data sources you add in future. If you don't check admin then you have to manually configure user permission for each data source.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/zappysys-data-gateway-add-user.png">
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-5453" src="https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-configure-add-user.png" alt="" width="564" height="438" srcset="https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-configure-add-user.png 564w, https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-configure-add-user-300x233.png 300w" sizes="(max-width: 564px) 100vw, 564px" /></a>
<p class="wp-caption-text">Adding the Gateway user</p>

</div></li>
</ol>
&nbsp;</div>
<h3>Create XML Driver Connection for Amazon MWS API (e.g. RequestReport )</h3>
<p>Some APIs we need to call in this article is XML format and some API (e.g. GetReport) is CSV format &#8211; Tab delimited so we need to create 2 different connections using CSV driver and XML driver. So lets get started with Amazon MWS Connection for XML API.</p>
<ol>
<li>Click on Add New Data source. Name as <strong>AMAZON-MWS-XML</strong> and select <a href="https://zappysys.com/products/odbc-powerpack/odbc-xml-soap-api-driver/" target="_blank" rel="noopener"><strong>Native &#8211; ZappySys XML Driver</strong></a> option.
<div id="attachment_5557" style="width: 572px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc_json_driver_add_native_driver.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-5557" class="size-full wp-image-5557" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc_json_driver_add_native_driver.png" alt="Add Gateway Data Source" width="562" height="539" srcset="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc_json_driver_add_native_driver.png 562w, https://zappysys.com/blog/wp-content/uploads/2018/11/odbc_json_driver_add_native_driver-300x288.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></a><p id="caption-attachment-5557" class="wp-caption-text">Add Gateway Data Source</p></div></li>
<li>Now click Edit to Configure Settings. For now we will only care OAuth Connection settings. All other options are overwritten in SQL Query.
<div id="attachment_5440" style="width: 572px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-create-datasource-2-2.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-5440" class="size-full wp-image-5440" src="https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-create-datasource-2-2.png" alt="Edit Gateway Data Source Settings" width="562" height="385" srcset="https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-create-datasource-2-2.png 562w, https://zappysys.com/blog/wp-content/uploads/2018/11/gateway-create-datasource-2-2-300x206.png 300w" sizes="(max-width: 562px) 100vw, 562px" /></a><p id="caption-attachment-5440" class="wp-caption-text">Edit Gateway Data Source Settings</p></div></li>
<li>When UI opens for Driver Enter MWS API Service URL as below. Notice that we added /Products/2011-10-01 (This was extracted from previous section). You can check <a href="https://docs.developer.amazonservices.com/en_ES/dev_guide/DG_Endpoints.html" target="_blank" rel="noopener">full list of Amazon MWS Endpoints here</a>. Because we are connecting to USA region we will use below URL.<br />
<pre class="crayon-plain-tag">https://mws.amazonservices.com/Products/2011-10-01</pre>
</li>
<li>Select <strong>OAuth</strong> from the Connection dropdown and Click <strong>Configure Settings</strong></li>
<li>On the Connection UI, Select OAuth Provider <strong>Amazon Market Web Service (MWS)</strong></li>
<li>Enter your API <strong>Access Key</strong> and <strong>Secret Key</strong> (obtained <a href="https://sellercentral.amazon.com/gp/account-manager/home.html/ref=xx_userperms_dnav_userperms" target="_blank" rel="noopener">from here</a>)</li>
<li>Your connection will look like below.
<div id="attachment_4850" style="width: 667px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-odbc-driver-connection.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-4850" class="size-full wp-image-4850" src="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-odbc-driver-connection.png" alt="ODBC Connection Credentials for Amazon MWS API (Access Key, Secret Key, URL Endpoint)" width="657" height="570" srcset="https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-odbc-driver-connection.png 657w, https://zappysys.com/blog/wp-content/uploads/2018/09/amazon-mws-api-odbc-driver-connection-300x260.png 300w" sizes="(max-width: 657px) 100vw, 657px" /></a><p id="caption-attachment-4850" class="wp-caption-text">ODBC Connection Credentials for Amazon MWS API (Access Key, Secret Key, URL Endpoint)</p></div></li>
<li>Also configure Retry options to handle API limit reached error when you call API too often. For Amazon MWS we get Status code 503 when request is throttled so lets narrow down on which error we want to retry.
<div id="attachment_7156" style="width: 599px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/09/http-retry-settings-oauth-connection.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7156" class="size-full wp-image-7156" src="https://zappysys.com/blog/wp-content/uploads/2018/09/http-retry-settings-oauth-connection.png" alt="Retry Options" width="589" height="429" srcset="https://zappysys.com/blog/wp-content/uploads/2018/09/http-retry-settings-oauth-connection.png 589w, https://zappysys.com/blog/wp-content/uploads/2018/09/http-retry-settings-oauth-connection-300x219.png 300w" sizes="(max-width: 589px) 100vw, 589px" /></a><p id="caption-attachment-7156" class="wp-caption-text">Retry Options</p></div></li>
<li>Click OK to save OAuth Connection UI to go back to main UI</li>
<li>Now Go to Throttling Tab and enter some delay (e.g. <strong>enter 20000 for 20sec delay after each request</strong>). This will slow down API calls so we don&#8217;t face errors about API Limit reached.</li>
<li>Click OK to Save UI</li>
<li>Click Save button on Gateway UI to save and restart</li>
</ol>
<h3>Create CSV Driver Connection for Amazon MWS API (e.g. GetReport )</h3>
<p>Now lets create a connection CSV API (e.g. <a href="https://docs.developer.amazonservices.com/en_UK/reports/Reports_GetReport.html" target="_blank" rel="noopener">GetReport</a> ).</p>
<p>Follow almost same steps as previous section except use CSV Driver when you click on Add new Data source select <strong><a href="https://zappysys.com/products/odbc-powerpack/odbc-csv-rest-api-driver/" target="_blank" rel="noopener">Native &#8211; ZappySys CSV Driver</a></strong> and name data source as <strong>AMAZON-MWS-CSV</strong> . As we mentioned for now we mostly want to setup Connection and not worry about Request Body, Pagination etc.</p>
<h3>Create Linked Server for SQL Server</h3>
<p>Run following Script in SSMS to create Linked servers. Change ######## with Your gateway password. Change localhost with machine name or IP where ZappySys Gateway Is running. Use localhost if SQL Server and Gateway both on the same machine.</p><pre class="crayon-plain-tag">USE [master]
GO

EXEC master.dbo.sp_addlinkedserver @server = N'AMAZON-MWS-XML', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'localhost,5000', @catalog=N'AMAZON-MWS-XML'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'AMAZON-MWS-XML',@useself=N'False',@locallogin=NULL,@rmtuser=N'tdsuser',@rmtpassword='########'
GO

EXEC master.dbo.sp_addlinkedserver @server = N'AMAZON-MWS-CSV', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'localhost,5000', @catalog=N'AMAZON-MWS-CSV'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'AMAZON-MWS-CSV',@useself=N'False',@locallogin=NULL,@rmtuser=N'tdsuser',@rmtpassword='########'
GO</pre><p>
If you want to know how to configure Linked Server using UI then <a href="https://zappysys.com/blog/import-rest-api-json-sql-server/" target="_blank" rel="noopener">check this article</a>.</p>
<p>&nbsp;</p>
<h2>Amazon MWS ListOrders Example</h2>
<p>Now lets look at how to call ListOrders request with pagination in SQL Server. Create a following Stored Procedure to List MWS Orders. If you want to extract many orders then call Report rather than this proc (See next section for generating reports)</p><pre class="crayon-plain-tag">USE MyDatabase
GO
/*
Example: 
 exec usp_MWS_ListOrders @SellerId='Axxxxxxx', @MarketplaceId ='Bxxxxxxx',@CreatedAfter='2019-01-01'  
*/
Create proc [dbo].[usp_MWS_ListOrders]
	@SellerId varchar(100),
	@MarketplaceId varchar(100),
	@CreatedAfter varchar(100),
	@CreatedBefore varchar(100)=null,
	@MaxRows int=0
as
declare @sql varchar(max) 
declare @limitClase varchar(100)=''
if(@MaxRows&gt;0)
	set @limitClase	=' LIMIT ' + cast(@MaxRows as varchar(20))

--//Confirm ISO Date format 2019-06-01T04%3A00%3A00Z  rather 2019-06-01T04:00:00Z
if(isnull(@CreatedAfter,'')&lt;&gt;'')
begin
	set @CreatedAfter='&amp;CreatedAfter=' + @CreatedAfter
	set @CreatedAfter=replace(@CreatedAfter,':','%3A')
	if(@CreatedAfter NOT LIKE @CreatedAfter + 'T%')
		set @CreatedAfter=@CreatedAfter + 'T00%3A00%3A00Z'
	if(@CreatedAfter NOT LIKE @CreatedAfter + '%Z')
		set @CreatedAfter=@CreatedAfter + 'Z'
	--//T04%3A00%3A00Z
end
if(isnull(@CreatedBefore,'')&lt;&gt;'')
begin
	set @CreatedBefore='&amp;CreatedBefore=' + @CreatedBefore
	set @CreatedBefore=replace(@CreatedBefore,':','%3A')
	if(@CreatedBefore NOT LIKE @CreatedBefore + 'T%')
		set @CreatedBefore=@CreatedBefore + 'T00%3A00%3A00Z'
	if(@CreatedBefore NOT LIKE @CreatedBefore + '%Z')
		set @CreatedBefore=@CreatedBefore + 'Z'
end

set @CreatedAfter = isnull(@CreatedAfter,'')
set @CreatedBefore = isnull(@CreatedBefore,'')


set @sql = 'SELECT * FROM OPENQUERY([AMAZON-MWS-XML]
, ''
SELECT ReportRequestId FROM $
' + @limitClase +' 
WITH(
     Src=''''https://mws.amazonservices.com/Orders/2013-09-01''''
	,Filter=''''$.RequestReportResponse.RequestReportResult.ReportRequestInfo''''
	,ElementsToTreatAsArray=''''Order''''
	,RequestData=''''Action=ListOrders[$tag$]' + @CreatedAfter + @CreatedBefore + '&amp;MarketplaceId.Id.1='+ @MarketplaceId +'&amp;SellerId='+ @SellerId +'''''
	,RequestMethod=''''POST''''
	,NextUrlAttributeOrExpr=''''$.ListOrders[$tag$]Response.ListOrders[$tag$]Result.NextToken''''
	,NextUrlSuffix=''''&amp;NextToken=&lt;%nextlink_encoded%&gt;''''
	,WaitTimeMs=20000 -- slow down to avoid throttling. 6 requests per min
	,HasDifferentNextPageInfo=''''True''''
	,EnablePageTokenForBody=''''True''''
	,PagePlaceholders=''''body=|ByNextToken;filter=|ByNextToken''''
	--,DataConnectionType=''''OAuth''''
	--,ScopeSeparator=''''{space}''''
	--,ServiceProvider=''''AmazonMWS''''
	--,ClientId=''''AKIxxxxxx''''
	--,ClientSecret=''''AKIxxxxxx''''
	--,UseCustomApp=''''True''''
	,CacheFileLocation=''''c:\temp\mws-orders.cache''''
	,CacheEntryTtl=300 --send every 5 mins else use from cache
	,IncludeParentColumns=''''False''''
)
'')'
print @sql

EXECUTE( @sql)</pre><p>
Here is how to call this proc. Change SellerId, MarketplaceId and Date.</p><pre class="crayon-plain-tag">exec usp_MWS_ListOrders @SellerId='Axxxxxxx', @MarketplaceId ='Bxxxxxxx',@CreatedAfter='2019-01-01'</pre><p>
&nbsp;</p>
<h2>Download Amazon MWS Report data in SQL Server (CSV / XML Format)</h2>
<p>Now lets look at how to extract data from <a href="https://docs.developer.amazonservices.com/en_UK/reports/Reports_ReportType.html" target="_blank" rel="noopener">Custom Report API</a> (You must need ODBC PowerPack <strong>v1.1.1</strong> or higher). However reading data from Reports not single step process because report generation is Job style API. Which means you send report request and wait  until its done. Once Report ready you have to read in CSV format or XML. Some Reports only available in CSV format. <a href="https://docs.developer.amazonservices.com/en_UK/reports/Reports_Overview.html" target="_blank" rel="noopener">Check this post</a> to understand how complex it can be to get data. We will make it simple for you to understand this in 3 steps. Basically calling reports requires minimum 3 API calls (see below)</p>
<ol>
<li>Create a new report request &#8211; Cal <a href="https://docs.developer.amazonservices.com/en_UK/reports/Reports_RequestReport.html" target="_blank" rel="noopener">RequestReport</a> API . It returns <strong>ReportRequestId</strong> (You can use it in the next step)</li>
<li>Check Report Status see its done &#8211; Call <a href="https://docs.developer.amazonservices.com/en_UK/reports/Reports_GetReportRequestList.html" target="_blank" rel="noopener">GetReportRequestList</a> API (Pass <strong>ReportRequestId</strong> got in the previous step to get data for only one Report request we care). Keep checking Report Status every few seconds until you get <strong>_DONE_</strong>  or <strong>_DONE_NO_DATA_</strong> status in response.</li>
<li>Read Report Data &#8211; Call <a href="https://docs.developer.amazonservices.com/en_UK/reports/Reports_GetReport.html" target="_blank" rel="noopener">GetReport</a>. This API call returns CSV or XML data. So use correct Driver for this step. If CSV data is returned then we must use CSV Driver rather than XML Driver.</li>
</ol>
<h3>Method 1 &#8211; Single query approach (New Driver)</h3>
<p>In new driver ZappySys added few new features which makes it possible to call above 3 steps process in a single query. New query syntax offers StatusCheck and Mixing Content Formats using same driver. Because Most MWS Reports are in CSV Format we have to use CSV Driver but oddly first 2 steps listed in above sections are in XML Format so we have to use XML driver. Technically we need atleast 2 steps (i.e 2 queries) but we will show you how to achieve using single query as below.</p>
<ol>
<li>Assuming you have followed steps to create a linked server AMAZON-MWS-CSV (see previous section)</li>
<li>Run below query. Replace necessary parameters as per your need. (i.e MarketplaceId , SellerId, CreatedAfter date)<br />
<pre class="crayon-plain-tag">--- //////////////////////////////////////////////////////////////////////////
-- Change _GET_MERCHANT_LISTINGS_DATA_ to something else if you need different report type (all 3 steps) -- https://docs.developer.amazonservices.com/en_US/reports/Reports_ReportType.html
-- Replace MarketplaceId in all 3 steps (i.e for USA use ATVPDKIKX0DER) --https://docs.developer.amazonservices.com/en_US/dev_guide/DG_Endpoints.html
-- Replace SellerId in all 3 steps
-- Remove or Change CreatedAfter in first step (or use CreatedBefore parameter instread of CreatedAfter)
--- //////////////////////////////////////////////////////////////////////////
select * into tmpMWS_Report from OPENQUERY([AMAZON-MWS-CSV],
'
SELECT s3.* FROM $
WITH(
Src=''https://mws.amazonservices.com/Reports/2009-01-01'',RequestMethod=''POST''
,RequestData=''Action=RequestReport&amp;ReportType=_GET_MERCHANT_LISTINGS_DATA_&amp;MarketplaceId=ATVPDKIKX0DER&amp;SellerId=Axxxxxxxxxx&amp;CreatedAfter=2017-12-31T04%3A00%3A00Z''
,IncludeParentColumns=''False''
,EnableRawOutputModeSingleRow=''True''
,RawOutputFilterExpr=''//*[local-name()="ReportRequestId"]'' 
,RawOutputDataRowTemplate=''{ReportRequestId:"[$1]"}'' 
,RawOutputExtractMode=''Xml'' 
,WaitTimeMs=5000
,Meta=''[{"Name": "ReportRequestId","Type": "Int64"}]''
,Alias=''s1''

,Join1_alias=''s2''	
,Join1_Src=''https://mws.amazonservices.com/Reports/2009-01-01'',Join1_RequestMethod=''POST''
,Join1_RequestData=''Action=GetReportRequestList&amp;ReportRequestIdList.Id.1=[$s1.ReportRequestId$]&amp;MarketplaceId=ATVPDKIKX0DER&amp;SellerId=Axxxxxxxxxxxxx''
,Join1_EnableRawOutputModeSingleRow=''True''
,Join1_RawOutputFilterExpr=''//*[local-name()="ReportProcessingStatus"]||//*[local-name()="GeneratedReportId"]'' 
,Join1_RawOutputDataRowTemplate=''{ReportProcessingStatus:"[$1]",GeneratedReportId:"[$2]"}'' 
,Join1_RawOutputExtractMode=''Xml'' 
,Join1_EnableStatusCheck=''True'', 
,Join1_StatucCheckMaxWaitSeconds=300,
,Join1_StatucCheckIterationWaitSeconds=25,
,Join1_StatusSuccessValue=''_DONE_''
,Join1_StatusFailedValue=''_DONE_NO_DATA_|_CANCELLED_''

,Join2_Alias=''s3''
,Join2_Src=''https://mws.amazonservices.com/Reports/2009-01-01'',Join2_RequestMethod=''POST''
,Join2_RequestData=''Action=GetReport&amp;ReportId=[$s2.GeneratedReportId$]&amp;MarketplaceId=ATVPDKIKX0DER&amp;SellerId=Axxxxxxxxxxxxxx''	
,Join2_ColumnDelimiter=''{TAB}''
,Join2_ResponseCharset=''Windows-1252''	 
,Join2_EnableStatusCheck=''False'' 
,Join2_EnableRawOutputModeSingleRow=''False''
,Join2_WaitTimeMs=10000
)') 
go
select * from tmpMWS_Report</pre>
&nbsp;</li>
</ol>
<p>&nbsp;</p>
<p><strong>Performance Tip</strong></p>
<p>If you like to improve performance and dont want to use SELECT INTO approach to load into temp table as above then you can use EXEC (&#8230;.) AT YourLinkedServerName  as below.</p>
<p>Advantage of this method is your Query speed will increase because system calls API only once when you call EXEC AT. In OPENROWSET it needs to call above query twice (Once to obtain metadata and once to get data).</p><pre class="crayon-plain-tag">INSERT INTO tmpMWS_Report
EXEC('select s3.* .................. ') AT [AMAZON-MWS-CSV]</pre><p>
<div class="su-note"  style="border-color:#e5de9d;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#fff8b7;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;">When you use OPENQUERY / EXEC..AT with Data Gateway there is a known limitation with SQL Query Length. Your query must be less than 2048 characters otherwise you may get [**** Data is invalid error ****] Try to avoid column names for long query and use SELECT * INTO temp_table FROM OPENQUERY(&#8230;..) approach. </div></div>
<p>&nbsp;</p>
<h3>Method 2 &#8211; Multiple query approach (For old driver)</h3>
<p>Now lets see how to load Amazon MWS data in SQL Server using <strong>old driver</strong> (<strong>v1.1.2 or older</strong>) which didnt support single query approach like previous section. If you are using older driver or for some reason you like to split steps into multiple procedures then use below approach.</p>
<h4>usp_MWS_Report  Stored Proc ( Generate ReportRequest, Wait until done, Read data )</h4>
<pre class="crayon-plain-tag">USE MyDatabase
GO

/*
Examples: 
Get ReportType from here https://docs.developer.amazonservices.com/en_UK/reports/Reports_ReportType.html

exec usp_MWS_Report @MarketplaceId ='ATVPDKIKX0DER', @SellerId='AZxxxxxxxx', @ReportType = '_GET_MERCHANT_LISTINGS_DATA_'
exec usp_MWS_Report @MarketplaceId ='ATVPDKIKX0DER', @SellerId='AZxxxxxxxx', @ReportType = '_GET_FLAT_FILE_ORDER_REPORT_DATA_'

--Do not Throw Error if no data found (return empty resultset or run custom sql)
exec usp_MWS_Report @MarketplaceId ='ATVPDKIKX0DER', @SellerId='AZxxxxxxxx', @ReportType = '_GET_FLAT_FILE_ORDER_REPORT_DATA_',@ThrowErrIfNoData=0,@EmptyRowSql='select top 0 * from Orders'
--Supply date range
exec usp_MWS_Report @MarketplaceId ='ATVPDKIKX0DER', @SellerId='AZxxxxxxxx', @ReportType = '_GET_MERCHANT_LISTINGS_DATA_', @StartDate='2019-01-01T00:00:00Z', @EndDate='2019-01-31T00:00:00Z'

--loading into table 

--//////////////////////////////////
— Step-1 : Create Local Linked server to point to self
--//////////////////////////////////
USE [master]
GO
--change default catalog
--For MSSQL 2012, 2014, 2016, 2017, and 2019 use @provider=N'MSOLEDBSQL' below (SQL Server Native Client 11.0)---
EXEC master.dbo.sp_addlinkedserver @server = N'ME', @srvproduct=N'', @provider=N'SQLNCLI11', @datasrc=N'localhost', @catalog=N'Northwind'
--For MSSQL 2022 or higher use @provider=N'MSOLEDBSQL' below (Microsoft OLE DB Driver for SQL Server)---
--EXEC master.dbo.sp_addlinkedserver @server = N'ME', @srvproduct=N'', @provider=N'MSOLEDBSQL', @datasrc=N'localhost', @catalog=N'Northwind'

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'ME',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO
--//////////////////////////////////
— Step-2 : Enable RPC OUT and Disable MSDTC
--//////////////////////////////////
EXEC sp_serveroption 'ME', 'rpc out', true;  
GO
--Below needed to support EXEC + INSERT (dynamic query)
EXEC sp_serveroption 'ME', 'remote proc transaction promotion', false;
GO
--test simple query
select * from OPENQUERY(ME,'select 1')
GO

--//////////////////////////////////
— Step-3 : Load data into table from MWS Report
--//////////////////////////////////
SELECT * INTO #amazon_mws_report
FROM OPENQUERY(me,'
SET NOCOUNT ON;
EXEC usp_MWS_Report 
   @Columns=''[item-name], [item-description], [listing-id]'',
   @MarketplaceId =''ATVPDKIKX0DER'', 
   @SellerId=''Axxxxxxxxxxxxxxxxx'', 
   @ReportType = ''_GET_MERCHANT_LISTINGS_DATA_''
WITH RESULT SETS 
(
	(itmname varchar(1000),itmdesc varchar(1000),itmid varchar(1000))
)
')

select * from #amazon_mws_report


*/
CREATE proc [dbo].[usp_MWS_Report]
	@MarketplaceId varchar(100),
	@SellerId varchar(100),
	@ReportType varchar(100)='_GET_MERCHANT_LISTINGS_DATA_',
	@StartDate varchar(100)=null,
	@EndDate varchar(100)=null,
	@ReportId bigint=null,  ---i.e. 14783134522018025
	@ThrowErrIfNoData bit=1,
	@EmptyRowSql varchar(1000)=null, --SQL to run if no data found
	@Columns varchar(8000)='*'  --report columns which goes in final SELECT  e.g. [item-name], [item-description], [listing-id] ....
as


declare @retGeneratedReportId bigint
set @retGeneratedReportId=@ReportId
---////// STEP 1 /////////
if(@ReportId is null)
begin
	create table #step1(ReportRequestId bigint)
	insert into #step1
	exec usp_MWS_RequestReport @ReportType,@MarketplaceId,@SellerId,@StartDate,@EndDate

	--select * from #step1 --debug

	declare @retReportRequestId bigint
	select @retReportRequestId=ReportRequestId from #step1

	---////// STEP 2 /////////
	declare @status varchar(100)
	declare @cnt int
	create table #step2(ReportProcessingStatus varchar(100),GeneratedReportId bigint)
	
	--Keep looping until status is done or we waited too long
	while(isnull(@status,'') IN ('','_SUBMITTED_','_IN_PROGRESS_') )
	begin
		truncate table #step2
		insert into #step2
		exec usp_MWS_GetReportIdAndStatus @retReportRequestId,@MarketplaceId,@SellerId 
	
		select @status=ReportProcessingStatus, @retGeneratedReportId=GeneratedReportId from #step2
		if(isnull(@status,'') IN ('','_SUBMITTED_','_IN_PROGRESS_') )			
		begin
			--amazon says dont check often https://docs.developer.amazonservices.com/en_UK/reports/Reports_GetReportRequestList.html
			Print 'Status='+  isnull(@status,'') +'. Checking after 45 sec... #' + cast(@cnt as varchar(10))
			WAITFOR DELAY '00:00:45'			
		end
		else
			print @status

		set @cnt=@cnt+1

		--if(@cnt&gt;50)
			--//throw err?
	end
	--select * from #step2 --debug
end

if(@retGeneratedReportId is null and @status='_DONE_NO_DATA_')
begin
	if(@ThrowErrIfNoData=1)
		RAISERROR('Cannot generate report - No data found for specified criteria',16,1); 
	else if (isnull(@EmptyRowSql,'')&lt;&gt;'')
		execute(@EmptyRowSql)
end
else if(@retGeneratedReportId is null)
	RAISERROR('Cannot generate report - Unknown error (either report got cancelled or other error occurred)',16,1); 

	
---////// STEP 3 /////////
--If xml format of report data then use XML driver else CSV (most are Tab delimited reports in CSV format)
--exec usp_MWS_GetReportDataXml @retGeneratedReportId,@MarketplaceId,@SellerId
exec usp_MWS_GetReportDataCsv @retGeneratedReportId,@MarketplaceId,@SellerId,@Columns

drop table #step1
drop table #step2

GO</pre>
&nbsp;</p>
<h4>usp_MWS_RequestReport  Stored Proc ( Step1 &#8211; Create Report Request )</h4>
<p>&nbsp;</p><pre class="crayon-plain-tag">USE [MyDatabase]
GO

CREATE proc [dbo].[usp_MWS_RequestReport]
	@ReportType varchar(100),
	@MarketplaceId varchar(100),
	@SellerId varchar(100),
	@StartDate varchar(100)=null,
	@EndDate varchar(100)=null
as

/*Learn more : https://docs.developer.amazonservices.com/en_UK/reports/Reports_RequestReport.html */

--//Confirm ISO Date format 2019-06-01T04%3A00%3A00Z  rather 2019-06-01T04:00:00Z
if(isnull(@StartDate,'')&lt;&gt;'')
begin
	set @StartDate='&amp;StartDate=' + @StartDate
	set @StartDate=replace(@StartDate,':','%3A')
	if(@StartDate NOT LIKE @StartDate + 'T%')
		set @StartDate=@StartDate + 'T00%3A00%3A00Z'
	if(@StartDate NOT LIKE @StartDate + '%Z')
		set @StartDate=@StartDate + 'Z'
	--//T04%3A00%3A00Z
end
if(isnull(@EndDate,'')&lt;&gt;'')
begin
	set @EndDate='&amp;EndDate=' + @EndDate
	set @EndDate=replace(@EndDate,':','%3A')
	if(@EndDate NOT LIKE @EndDate + 'T%')
		set @EndDate=@EndDate + 'T00%3A00%3A00Z'
	if(@EndDate NOT LIKE @EndDate + '%Z')
		set @EndDate=@EndDate + 'Z'
end

set @StartDate = isnull(@StartDate,'')
set @EndDate = isnull(@EndDate,'')

declare @sql varchar(max) 
set @sql = 'SELECT * FROM OPENQUERY([AMAZON-MWS-XML]
, ''
SELECT ReportRequestId FROM $
WITH(
	Src=''''https://mws.amazonservices.com/Reports/2009-01-01'''',RequestMethod=''''POST''''
	--,ElementsToTreatAsArray=''''Product''''
	,Filter=''''$.RequestReportResponse.RequestReportResult.ReportRequestInfo''''
	,RequestData=''''Action=RequestReport&amp;ReportType=' + @ReportType  + '&amp;MarketplaceId='+ @MarketplaceId +'&amp;SellerId='+ @SellerId + @StartDate + @EndDate +'''''
	,CacheFileLocation=''''c:\temp\mws-cache-step-1.cache''''
	,CacheEntryTtl=300 --send every 5 mins else use from cache
	,WaitTimeMs=''''300''''
	,IncludeParentColumns=''''False''''
	,Meta=''''[{"Name": "ReportRequestId","Type": "Int64"}]''''
)'')'
--print @sql

EXECUTE( @sql)
--sleep 25 seconds after this - hope report is ready by that time else We have to loop
WAITFOR DELAY '00:00:25'  --lets wait 30 sec... incase we get luck and report is done?
GO</pre><p>
&nbsp;</p>
<p>&nbsp;</p>
<h4>usp_MWS_GetReportIdAndStatus Stored Proc ( Step2 &#8211; Get Report Id and Report Status )</h4>
<p>&nbsp;</p><pre class="crayon-plain-tag">USE MyDatabase
GO


CREATE proc [dbo].[usp_MWS_GetReportIdAndStatus]
	@ReportRequestId bigint,
	@MarketplaceId varchar(100),
	@SellerId varchar(100)
as

declare @sql varchar(max) 
set @sql = 'SELECT * FROM OPENQUERY([AMAZON-MWS-XML]
, ''SELECT *  FROM $
WITH(
	 Src=''''https://mws.amazonservices.com/Reports/2009-01-01'''',RequestMethod=''''POST''''
	,ElementsToTreatAsArray=''''ReportRequestInfo''''
	,Filter=''''$.GetReportRequestListResponse.GetReportRequestListResult.ReportRequestInfo''''
	,RequestData=''''Action=GetReportRequestList&amp;ReportRequestIdList.Id.1=' + cast(@ReportRequestId as varchar(20)) + '&amp;MarketplaceId='+ @MarketplaceId +'&amp;SellerId='+ @SellerId +'''''
	,WaitTimeMs=''''300''''
	,IncludeParentColumns=''''False''''
	--,CacheFileLocation=''''c:\temp\mws-cache-step-2.cache''''
	--,CacheEntryTtl=10  --do not use from cache too old.. but cache still prevents too many requests
	,Meta=''''[{"Name": "ReportProcessingStatus","Type": "String", Length: 100},{"Name": "GeneratedReportId","Type": "Int64"}]''''	
)'')'

--print @sql

EXECUTE( @sql)

GO</pre><p>
&nbsp;</p>
<h4>usp_MWS_GetReportDataCsv Stored Proc (Step3 &#8211; Get Report Data in CSV format )</h4>
<p>Last step in report generation is download the report data in CSV format.</p><pre class="crayon-plain-tag">USE MyDatabase
GO

CREATE proc [dbo].[usp_MWS_GetReportDataCsv]
	@ReportId bigint,
	@MarketplaceId varchar(100),
	@SellerId varchar(100),
	@Columns varchar(8000)='*'

as

declare @sql varchar(max) 
set @sql = 'SELECT '+ @Columns +' FROM OPENQUERY([AMAZON-MWS-CSV], 
''SELECT * FROM $
WITH(
    Src=''''https://mws.amazonservices.com/Reports/2009-01-01'''',RequestMethod=''''POST''''
	,RequestData=''''Action=GetReport&amp;ReportId=' + cast(@ReportId as varchar(20)) + '&amp;MarketplaceId='+ @MarketplaceId +'&amp;SellerId='+ @SellerId +'''''
	,WaitTimeMs=''''300''''
	,ColumnDelimiter=''''{TAB}''''
	,ResponseCharset=''''Windows-1252''''	
	,CacheFileLocation=''''c:\temp\mws-cache-step-3.cache''''
	,CacheEntryTtl=300 --once report is generated lets try to read from cache 
	)''
)'

print @sql

EXECUTE( @sql)
GO</pre><p>
&nbsp;</p>
<h4>Example &#8211; Import data from Amazon MWS into SQL Server Table</h4>
<p>Finally when we have all stored procs created we can load into target table as below. In our previous article we saw how to use SELECT INTO along with OPENQUERY to load data into new temp table or insert into some existing table. However when you want to load Stored Proc output into table its not straight forward specially when we calling dynamic SQL.</p>
<p>Three tricks worth mentioning here which makes it possible to load data from stored proc into temp table dynamically.</p>
<ol>
<li>Create a linked server to Self so we can use OPENQUERY against to call stored proc so its easy to use <strong>SELECT INTO</strong>.</li>
<li>Use <strong>WITH RESULT SETS</strong> to describe metadata of output. This is needed because we are using dynamic SQL inside proc and WITH RESULT SETS describes the metadata.</li>
<li>Use of SET NO COUNT ON to avoid error like below<br />
<pre class="crayon-plain-tag">"SOMESERVERNAME" indicates that either the object has no columns 
or the current user does not have permissions on that object</pre>
</li>
<li>If you dont do above tricks then you may see errors like <a href="https://stackoverflow.com/questions/3795263/errors-insert-exec-statement-cannot-be-nested-and-cannot-use-the-rollback-s" target="_blank" rel="noopener">this</a> (INSERT is not allowed when we use DYNAMIC SQL inside nested Stored Procs)</li>
</ol>
<p>To load output into table you must know column names from the output.  If you dont know you can try to run stored proc without @Columns like below.</p><pre class="crayon-plain-tag">EXEC usp_MWS_Report @MarketplaceId =''ATVPDKIKX0DER'', @SellerId=''Axxxxxxxxxxxxx'', @ReportType = ''_GET_MERCHANT_LISTINGS_DATA_''</pre><p>
Once we know columns from report, you can run following script to insert into table.</p>
<p><strong>Full Script &#8211; Load MWS Report Output into Table</strong></p><pre class="crayon-plain-tag">--//////////////////////////////////
— Step-1 : Create Local Linked server to point to self
--//////////////////////////////////
USE [master]
GO
--change default catalog
--For MSSQL 2012, 2014, 2016, 2017, and 2019 use @provider=N'MSOLEDBSQL' below (SQL Server Native Client 11.0)---
EXEC master.dbo.sp_addlinkedserver @server = N'ME', @srvproduct=N'', @provider=N'SQLNCLI11', @datasrc=N'localhost', @catalog=N'Northwind'
--For MSSQL 2022 or higher use @provider=N'MSOLEDBSQL' below (Microsoft OLE DB Driver for SQL Server)---
--EXEC master.dbo.sp_addlinkedserver @server = N'ME', @srvproduct=N'', @provider=N'MSOLEDBSQL', @datasrc=N'localhost', @catalog=N'Northwind'

EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'ME',@useself=N'True',@locallogin=NULL,@rmtuser=NULL,@rmtpassword=NULL
GO
--//////////////////////////////////
— Step-2 : Enable RPC OUT and Disable MSDTC
--//////////////////////////////////
EXEC sp_serveroption 'ME', 'rpc out', true;  
GO
--Below needed to support EXEC + INSERT (dynamic query)
EXEC sp_serveroption 'ME', 'remote proc transaction promotion', false;
GO
--test simple query
select * from OPENQUERY(ME,'select 1')
GO

--//////////////////////////////////
— Step-3 : Load data into temp table from Amazon MWS Report
--//////////////////////////////////
SELECT * INTO #amazon_mws_report
FROM OPENQUERY(me,'
SET NOCOUNT ON;
EXEC usp_MWS_Report 
   @Columns=''[item-name], [item-description], [listing-id]'',
   @MarketplaceId =''ATVPDKIKX0DER'', 
   @SellerId=''Axxxxxxxxxxxxx'', 
   @ReportType = ''_GET_MERCHANT_LISTINGS_DATA_''
WITH RESULT SETS 
(
	(itmname varchar(1000),itmdesc varchar(1000),itmid varchar(1000))
)
')

select * from #amazon_mws_report</pre><p>
<div id="attachment_7192" style="width: 865px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2019/05/import-amazon-mws-data-into-sql-server-table-generate-report.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7192" class="size-full wp-image-7192" src="https://zappysys.com/blog/wp-content/uploads/2019/05/import-amazon-mws-data-into-sql-server-table-generate-report.png" alt="Import Amazon MWS Data into SQL Table (Load Report output into temp table)" width="855" height="499" srcset="https://zappysys.com/blog/wp-content/uploads/2019/05/import-amazon-mws-data-into-sql-server-table-generate-report.png 855w, https://zappysys.com/blog/wp-content/uploads/2019/05/import-amazon-mws-data-into-sql-server-table-generate-report-300x175.png 300w, https://zappysys.com/blog/wp-content/uploads/2019/05/import-amazon-mws-data-into-sql-server-table-generate-report-768x448.png 768w" sizes="(max-width: 855px) 100vw, 855px" /></a><p id="caption-attachment-7192" class="wp-caption-text">Import Amazon MWS Data into SQL Table (Load Report output into temp table)</p></div>
<h2>Conclusion</h2>
<p>In this article, we saw how to load Amazon MWS Data into SQL Server. We used simple SQL queries with ZappySys XML / CSV Driver to pull data from Amazon MWS API. <a href="https://zappysys.com/products/odbc-powerpack/">ZappySys ODBC PowerPack</a> makes it super easy to consume data from virtually any API (JSON / XML or CSV Web Services), no coding required. <a href="https://zappysys.com/products/odbc-powerpack/download/">Download here</a> to get started with ZappySys ODBC drivers.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>The post <a href="https://zappysys.com/blog/import-amazon-mws-data-sql-server-t-sql/">How to import Amazon MWS data into SQL Server (T-SQL)</a> appeared first on <a href="https://zappysys.com/blog">ZappySys Blog</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to import REST API in SQL Server (Call JSON / XML SOAP Service)</title>
		<link>https://zappysys.com/blog/import-rest-api-json-sql-server/</link>
		
		<dc:creator><![CDATA[ZappySys Team]]></dc:creator>
		<pubDate>Fri, 09 Mar 2018 20:23:23 +0000</pubDate>
				<category><![CDATA[JSON File / REST API Driver]]></category>
		<category><![CDATA[ODBC Gateway]]></category>
		<category><![CDATA[ODBC PowerPack]]></category>
		<category><![CDATA[T-SQL (SQL Server)]]></category>
		<category><![CDATA[XML File / SOAP API Driver]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[linked server]]></category>
		<category><![CDATA[odbc]]></category>
		<category><![CDATA[polybase]]></category>
		<category><![CDATA[rest api]]></category>
		<category><![CDATA[soap]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[xml]]></category>
		<guid isPermaLink="false">https://zappysys.com/blog/?p=2921</guid>

					<description><![CDATA[<p>Introduction In this article, you will see few Examples to import REST API in SQL Server Table (Call JSON / XML SOAP API).  You will also learn how to load JSON Files into SQL Server Table using T-SQL Stored procedure code.  So let&#8217;s get ready for fun 🙂 JSON File format and REST API (i.e. RESTful [&#8230;]</p>
<p>The post <a href="https://zappysys.com/blog/import-rest-api-json-sql-server/">How to import REST API in SQL Server (Call JSON / XML SOAP Service)</a> appeared first on <a href="https://zappysys.com/blog">ZappySys Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[<h2>Introduction</h2>
<p><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/json-to-sql-server-import-export.png"><img loading="lazy" decoding="async" class="alignleft wp-image-2924 size-thumbnail" src="https://zappysys.com/blog/wp-content/uploads/2018/03/json-to-sql-server-import-export-150x150.png" alt="JSON to SQL Server" width="150" height="150" /></a>In this article, you will see few <strong>Examples to import REST API in SQL Server Table (Call JSON / XML SOAP API). </strong> You will also learn <strong>how to load JSON Files into SQL Server Table using T-SQL Stored procedure</strong> code.  So let&#8217;s get ready for fun 🙂</p>
<p>JSON File format and REST API (i.e. RESTful API ) is becoming more and more popular each day. You may already have some data integration scenarios to <strong>read/write From REST API services in SQL Server</strong> or maybe API integration in other Apps such as Power BI, Tableau, SSIS, Informatica.</p>
<p>REST API integration can be challenging without the right set of tools. Even for highly skilled programmer sometimes its difficult to achieve the desired result.  But not to worry at the end of this article you will find out how easy it is to <strong>pull data from JSON / XML based web service using familiar SQL Query Language.</strong>  In the next few sections, you will learn how to call REST API inside SQL Server using familiar T-SQL code.</p>
<h2>Steps to Import JSON / XML REST API in SQL Server</h2>
<p>Here is the summary of steps to query REST API / JSON File in SQL Server (Using T-SQL code). For detailed steps read the full article and watch the video tutorial.</p>
<ol>
<li>Install <strong>ZappySys ODBC PowerPack </strong> <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">from here</a> (it contains drivers for JSON / XML API)</li>
<li>Create <strong>ODBC DSN</strong> for JSON / XML API Source</li>
<li>Configure <strong>ZappySys Data Gateway Service</strong> so SQL Server can use ZappySys Drivers in T-SQL code</li>
<li>Create and <strong>Configure Linked Server</strong> to connect to JSON / REST API Service</li>
<li>Write some <strong>T-SQL code</strong> in your stored procedure like below to import data from JSON / REST Service
<div id="attachment_3278" style="width: 866px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/example-import-json-rest-api-sql-server-tsql-stored-procedure.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-3278" class="size-full wp-image-3278" src="https://zappysys.com/blog/wp-content/uploads/2018/03/How-to-import-REST-API-in-SQL-Server-1.png" alt="Example - Import JSON Files / REST API Data inside SQL Server ( Call API using T-SQL Stored Procedure)" width="856" height="687" /></a><p id="caption-attachment-3278" class="wp-caption-text">Example &#8211; Import JSON / XMLFiles / REST API Data into SQL Server Table ( Call API using T-SQL Stored Procedure)</p></div></li>
</ol>
<p>&nbsp;</p>
<h2>Video Tutorial &#8211; Read from JSON / XML / REST API in SQL Server (T-SQL code)</h2>
<p>If you want to save time and go quick then check out following video tutorial on calling JSON / REST API Service in SQL Server code. Steps The following video will be useful to configure your Linked Server and query REST API. It shows how to configure ODBC DSN, ZappySys Data Gateway Server (Used for Linked Server). To see other use cases of ZappySys Data Gateway <a href="https://zappysys.com/blog/category/odbc-powerpack/odbc-gateway/" target="_blank" rel="noopener">click here</a></p>
[youtube url=&#8221;https://www.youtube.com/watch?v=fLx6_C39LOQ&#8221;]
<p>&nbsp;</p>
[youtube url=&#8221;https://www.youtube.com/watch?v=M_Pm02ZQT8A&#8221;]
<h2>Requirements</h2>
<ol>
<li>A first requirement will be to SQL Server Database Engine Installed</li>
<li>The second requirement will be SSMS installed</li>
<li>Make sure to have <a href="https://zappysys.com/products/odbc-powerpack/">ZappySys ODBC PowerPack</a> installed.</li>
<li> Another important requirement is the internet connection to connect to REST API information using a URL.</li>
</ol>
<h2>Step-By-Step : Load REST API in SQL Server</h2>
<p>In next few sections, you will see step-by-step approach to consume REST API / JSON data in SQL Server using T-SQL code.</p>
<h3>Configure ZappySys Data Gateway Service</h3>
<p>To call external Drivers (e.g. ZappySys JSON/REST API Driver) in SQL Server we have to use <a href="https://docs.microsoft.com/en-us/sql/relational-databases/linked-servers/linked-servers-database-engine?view=sql-server-2017" target="_blank" rel="noopener">Linked Server feature</a>. We will use <a href="https://zappysys.com/products/odbc-powerpack/data-gateway/" target="_blank" rel="noopener">ZappySys Data Gateway Service</a> along with SQL Linked Server to call ZappySys Drivers (e.g. JSON / XML API Drivers) using T-SQL Code in Stored Procedures.</p>
<div class="content_block" id="custom_post_widget-5282">Now let's look at how to configure <a href="https://zappysys.com/products/odbc-powerpack/data-gateway/" target="_blank" rel="noopener">ZappySys Data Gateway</a>. This feature acts as a bridge between Client App and ZappySys Drivers. Using data gateway you can use ZappySys Drivers inside applications / operating systems where ZappySys drivers may not be available directly for some reason (e.g. You don't have access to Server for Installation or System does not support ODBC drivers like JAVA programs). <a href="https://zappysys.com/blog/category/odbc-powerpack/odbc-gateway/">Click here to read more</a> on various use cases of Data Gateway.
<h4><span style="font-size: 14pt;">Configure Data Gateway User / Port</span></h4>
Now let's look at steps to configure Data Gateway after installation. We will also create a sample data source for ODATA API (i.e. JSON based REST API Service).
<ol>
 	<li>Assuming you have installed <a href="https://zappysys.com/products/odbc-powerpack/" target="_blank" rel="noopener">ZappySys ODBC PowerPack</a> using default options (Which also enables Data Gateway Service)</li>
 	<li>Search "Gateway" in your start menu and click ZappySys Data Gateway
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/start-menu-open-zappysys-data-gateway.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/start-menu-open-zappysys-data-gateway.png" alt="Open ZappySys Data Gateway" /></a>
<p class="wp-caption-text">Open ZappySys Data Gateway</p>

</div></li>
 	<li>First make sure Gateway Service is running (Verify Start icon is disabled)</li>
 	<li>Also verify Port on General Tab
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-1.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-1.png" alt="Port Number setting on ZappySys Data Gateway" /></a>
<p class="wp-caption-text">Port Number setting on ZappySys Data Gateway</p>

</div></li>
 	<li>Now go to Users tab. <strong>Click Add</strong> icon to add a new user. Check Is admin to give access to all data sources you add in future. If you don't check admin then you have to manually configure user permission for each data source.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-2.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-2.png" alt="Add Data Gateway User" /></a>
<p class="wp-caption-text">Add Data Gateway User</p>

</div></li>
</ol>
&nbsp;
<h4><span style="font-size: 14pt;">Configure Data Source</span></h4>
<ol>
 	<li>After user is added, go to Data Sources tab. <strong>Click Add</strong> icon to create new data source. Select appropriate driver based on your API / File format. You can choose Generic ODBC option to read data from ODBC DSN or use Native Driver option.
<pre class=""><strong>NOTE:</strong> Whenever possible use native driver option for better performance / security and ease of use.</pre>
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-3.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-3.png" alt="Add Gateway Data Source (Native JSON Driver)" /></a>
<p class="wp-caption-text">Add Gateway Data Source (Native JSON Driver)</p>

</div></li>
 	<li>Click on "Edit" under Data source and configure as per your need (e.g. Url, Connection, Request Method, Content Type, Body, Pagination etc.). For this demo we are going to pick simple JSON REST API which doesn't need any authentication.  Enter following URL.
<pre class="">https://services.odata.org/V3/Northwind/Northwind.svc/Invoices?$format=json</pre>
</li>
 	<li>You can also view response structure and select default hierarchy (i.e. Filter) like below (Select Array Icon) for data extraction.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-4.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-4.png" alt="Configure JSON API Data source" /></a>
<p class="wp-caption-text">Configure JSON API Data source</p>

</div></li>
</ol>
<h4><span style="font-size: 14pt;">Test SQL Query / Preview Data</span></h4>
<ol>
 	<li>Now go to Preview Tab. You can click Preview button to execute default query
OR
Select Table name from dropdown to generate SQL with column names.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-5.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-5.png" alt="JSON / REST API Driver Query Preview / Query Examples (Read REST API or JSON Files)" /></a>
<p class="wp-caption-text">JSON / REST API Driver Query Preview / Query Examples (Read REST API or JSON Files)</p>

</div></li>
 	<li>You can also click Query Builder to generate SQL using different options in WITH clause. ANy setting you specify in WITH clause will override UI settings we applied in previous steps.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-6.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-6.png" alt="Using SQL Query Builder (For Files or REST / SOAP API - JSON / XML / CSV Format)" /></a>
<p class="wp-caption-text">Using SQL Query Builder (For Files or REST / SOAP API - JSON / XML / CSV Format)</p>

</div></li>
 	<li>There is another useful option for code generation. Select your Language and quickly copy code snippet. See below Example of XML Driver Query to call SOAP API.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-7.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/odbc-configure-data-gateway-json-7.png" alt="Generate Example Code for ZappySys Driver" /></a>
<p class="wp-caption-text">Generate Example Code for ZappySys Driver</p>

</div></li>
 	<li><strong>Click OK</strong> to Close Data Source UI</li>
 	<li>Once data source is tested and configured you can <strong>click Save </strong>button in the Gateway UI toolbar and click <strong>Yes</strong> for <strong>Restart Service</strong>.</li>
</ol>
&nbsp;</div>
<h4>Why use ZappySys Data Gateway Service?</h4>
<p>Gateway Service is useful to call ZappySys driver from any other machine without installing ZappySys driver. For example your Unix server can consume API data by connecting to ZappySys Data Gateway (which can be running on Remote Windows OS). Many times you cannot access remote server but like to Query API data (<a href="https://zappysys.com/api/integration-hub/google-sheets-connector/sql-server?context=connector" target="_blank" rel="noopener">Google SpreadSheet Use case).</a> To learn more about other use cases <a href="https://zappysys.com/blog/category/odbc-powerpack/odbc-gateway/" target="_blank" rel="noopener">click here</a>.</p>
<div class="su-note"  style="border-color:#e5dd9d;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;"><div class="su-note-inner su-u-clearfix su-u-trim" style="background-color:#FFF7B7;border-color:#ffffff;color:#333333;border-radius:3px;-moz-border-radius:3px;-webkit-border-radius:3px;">ZappySys has made API integration in SQL Server extremely easy, fast and secure by using very <strong>innovative approach</strong> for Microsoft SQL Server. Unlike other ODBC drivers available in the market we use very different approach. We use lightweight proxy service called <strong>ZappySys Data Gateway</strong> which runs outside the SQL Server Process / Memory Space. There are many advantages of this approach.</p>
<ul>
<li>Unlike other ODBC drivers, our drivers don&#8217;t affect SQL Server performance because it&#8217;s never loaded in the same SQL Server Process giving you total process isolation.</li>
<li>ZappySys Data Gateway Service acts like a small SQL Server itself. So any machine or any process can send SQL query to read/write data from API services or JSON files as long as communication happens using <a href="https://msdn.microsoft.com/en-us/library/dd304523.aspx" target="_blank" rel="noopener"><strong>TDS Protocol</strong></a>.</li>
<li>You can connect to ZappySys Data Gateway service using any  <a href="https://msdn.microsoft.com/en-us/library/dd304523.aspx" target="_blank" rel="noopener"><strong>TDS Protocol</strong></a> compatible driver (e.g. Microsoft native drivers for SQL Server such as ODBC, JDBC, OLEDB, ADO.net) ).</li>
<li>You can connect from any platform (e.g. <strong>Linux, Mac or Windows</strong>) using standard SQL Server Driver (many times already installed with OS).</li>
<li>You don&#8217;t have to install ZappySys Driver on the client machine with this approach.</li>
</ul>
</div></div>
<h3>Call REST API in SQL Server (T-SQL Code) using Linked Server</h3>
<div class="content_block" id="custom_post_widget-5289">Once you configured data source in Gateway, we can now setup Linked Server in SQL Server to query API data.
<ol style="margin-left: 10px;">
 	<li>Assuming you have installed SQL Server and SSMS. If not then get both for FREE from here: <a href="https://www.microsoft.com/en-us/sql-server/sql-server-editions-express">Get SQL Server Express</a> and  <a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms" target="_blank" rel="noopener">Get SSMS</a></li>
 	<li>Open SSMS and connect to SQL Server.</li>
 	<li>Go to Root &gt; Server Objects &gt; Linked Servers node. Right click and click <strong>New Linked Server...
</strong>
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/create-new-linked-server-ssms.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/03/create-new-linked-server-ssms.png" alt="Add Linked Server in SQL Server" />
</a>
<p class="wp-caption-text">Add Linked Server in SQL Server</p>

</div></li>
 	<li> Now enter linked server name, select Provider as SQL Native Client</li>
 	<li>Enter data source as <strong><span class="lang:default decode:true crayon-inline">GatewayServerName,PORT_NUMBER</span></strong> where server name is where ZappySys Gateway is running (Can be same as SQL Server machine or remote machine). Default PORT_NUMBER is 5000 but confirm on Data gateway &gt; General tab incase its different.</li>
 	<li>Enter Catalog Name. This must match name from Data gateway Data sources grid &gt; Name column
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/ssms-sql-server-configure-linked-server-2.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/ssms-sql-server-configure-linked-server-2.png" alt="Configure Linked Server Provider, Catalog, Server, Port for ZappySys Data Gateway Connection" />
</a>
<p class="wp-caption-text">Configure Linked Server Provider, Catalog, Server, Port for ZappySys Data Gateway Connection</p>
</div>
<div style="color: #31708f;background-color: #d9edf7;border-color: #bce8f1;padding: 15px;margin-bottom: 20px;border: 1px solid transparent;border-radius: 4px;">
<strong>INFO:</strong><br/>
<ul>
    <li>
      For <strong>SQL Server 2012, 2014, 2016, 2017, and 2019</strong>, use the <em>SQL Server Native Client 11.0</em> as the Provider.
    </li>
    <li>
      For <strong>SQL Server 2022 or higher</strong>, use the <em>Microsoft OLE DB Driver for SQL Server</em> as the Provider.
    </li>
  </ul>
</div></li>
 	<li>Click on Security Tab and select last option "<strong>Be made using this security context</strong>". Enter your gateway user account here.</li>
<li>
        <p>Optional: Under the Server Options Tab, Enable <b>RPC</b> and <b>RPC Out</b> and Disable Promotion of Distributed Transactions<b>(MSDTC)</b>.</p>
		<div class="wp-caption alignnone">
			<img decoding="async" class="block margin-bottom-10 img-thumbnail" src="https://zappysys.com/blog/wp-content/uploads/2018/11/linked-server-options-rpc-msdtc.png" title="RPC and MSDTC Settings" alt="RPC and MSDTC Settings" />
			<p class="wp-caption-text">RPC and MSDTC Settings</p>
		</div>
        <hr />
        <p>
            You need to enable RPC Out if you plan to use <b><i>EXEC(...) AT [MY_LINKED_SERVER_NAME]</i></b> rather than OPENQUERY.
            <br />
            If don't enabled it, you will encounter the <i>'Server "MY_LINKED_SERVER_NAME" is not configured for RPC'</i> error.
        </p>
        <p>
            Query Example:
            <code class="sql">EXEC('Select * from Products') AT [MY_LINKED_SERVER_NAME]</code>
        </p>
        <hr />
        <p>
            If you plan to use <b><i>'INSERT INTO...EXEC(....) AT [MY_LINKED_SERVER_NAME]'</i></b> in that case you need to Disable Promotion of Distributed Transactions(MSDTC).
            <br />
            If don't disabled it, you will encounter the <i>'The operation could not be performed because OLE DB provider "SQLNCLI11/MSOLEDBSQL" for linked server "MY_LINKED_SERVER_NAME" was unable to begin a distributed transaction.'</i> error.
        </p>
        <p>
            Query Example:
<pre class="">Insert Into dbo.Products 
EXEC('Select * from Products') AT [MY_LINKED_SERVER_NAME]</pre>
        </p>
        <hr />
</li>
 	<li>Click OK to save Linked Server</li>
 	<li>In SSMS execute below SQL query to test your connectivity.
<pre class="">SELECT * FROM OPENQUERY( MY_LINKED_SERVER_NAME, 'SELECT * FROM $')</pre>
--OR--
<pre class="">SELECT * FROM OPENQUERY( MY_LINKED_SERVER_NAME, 
'SELECT * FROM $
 WITH (Src=''https://services.odata.org/V3/Northwind/Northwind.svc/Customers?$format=json''
 ,Filter=''$.value[*]''
 ,DataFormat=''OData''
)');</pre>
</li>
 	<li>Here is the preview after you run some REST API query in SQL Server. Notice that you can override default configuration by supplying <a href="https://zappysys.com/onlinehelp/odbc-powerpack/scr/json-odbc-driver-connectionstring.htm" target="_blank" rel="noopener">many parameters</a> in WITH clause (second query example in screenshot).
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/11/query-rest-api-sql-server-linked-server-openquery-zappysys-data-gateway.png">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/11/query-rest-api-sql-server-linked-server-openquery-zappysys-data-gateway.png" alt="SSMS Output - Query REST API via Linked Server OPENQUERY statement (Connect to ZappySys Data Gateway)" />
</a>
<p class="wp-caption-text">SSMS Output - Query REST API via Linked Server OPENQUERY statement (Connect to ZappySys Data Gateway)</p>

</div></li>
 	<li>You can wrap your queries inside View or wrap inside Stored procedure to parameterize. Here is an example of create view which calls REST API queries. Below View can be consumed like a normal table from any Tools or Programming Language which supports connectivity to SQL Server.
<pre class="lang:tsql decode:true ">CREATE VIEW dbo.vwApiInvoices 
AS 
/*Call REST API inside SQL Server View*/
SELECT * FROM OPENQUERY( LS , 
'SELECT * FROM $
WITH (Src=''https://services.odata.org/V3/Northwind/Northwind.svc/Invoices?$format=json''
	 ,Filter=''$.value[*]''
	 ,DataFormat=''OData''
)');

GO
</pre>
&nbsp;</li>
 	<li>Notice in above approach if you parameterize Stored Procedure then <a href="https://zappysys.com/blog/create-csv-list-sql-server-table-columns-datatypes/" target="_blank" rel="noopener">check this article to understand Dynamic Metadata</a>.</li>
 	<li>That's it. We are now ready to move forward with more interesting things in next section.</li>
</ol></div>
<p>Optionally, use these lines of code to create the linked server using T-SQL instead of using the UI:</p><pre class="crayon-plain-tag">/* Add Linked Server called RESTAPI-SV (change if needed) to access REST API via Data Gateway - JSON/REST Driver */
/* customer_api is just an example data source name - created on Data gateway UI */

EXEC master.dbo.sp_addlinkedserver 
	@server = N'RESTAPI-SV', 
	@srvproduct=N'', 
--- For MSSQL 2012, 2014, 2016, 2017, and 2019 use below (SQL Server Native Client 11.0)---
    @provider=N'SQLNCLI11',
--- For MSSQL 2022 or higher use below (Microsoft OLE DB Driver for SQL Server)---
--- @provider=N'MSOLEDBSQL',
	@datasrc=N'localhost,5000', 
	@catalog=N'customer_api'

/* Add login for Linked Server - This is same user account and password which you define on Users tab on ZappySys Data Gateway Config Tool */
EXEC master.dbo.sp_addlinkedsrvlogin 
	@rmtsrvname=N'RESTAPI-SV',
	@useself=N'False',
	@locallogin=NULL,
	@rmtuser=N'admin',
	@rmtpassword='adminP@ss!23'
GO
--//OTHER IMPORTANT OPTIONS
EXEC master.dbo.sp_serveroption @server=N'RESTAPI-SV', @optname=N'rpc', @optvalue=N'true'
GO

EXEC master.dbo.sp_serveroption @server=N'RESTAPI-SV', @optname=N'rpc out', @optvalue=N'true'
GO

--Increase default timeout for long running query (default is 600 sec)
--EXEC master.dbo.sp_serveroption @server=N'RESTAPI-SV', @optname=N'query timeout', @optvalue=N'1200'
GO

--Below needed to support EXEC + INSERT (dynamic query)
EXEC master.dbo.sp_serveroption @server=N'RESTAPI-SV', @optname=N'remote proc transaction promotion', @optvalue=N'false'
GO</pre><p>
&nbsp;</p>
<ol>
<li>Now it is time to create some queries. Let&#8217;s run a simple query to REST API:<br />
<pre class="crayon-plain-tag">select * from OPENQUERY([RESTAPI-SV] , 'SELECT * FROM value' )</pre>
</li>
<li>The query will show all the data from REST API:
<div id="attachment_2945" style="width: 684px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/query-resp-api-results.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2945" class="size-full wp-image-2945" src="https://zappysys.com/blog/wp-content/uploads/2018/03/query-resp-api-results.png" alt="Linked server query results" width="674" height="214" srcset="https://zappysys.com/blog/wp-content/uploads/2018/03/query-resp-api-results.png 674w, https://zappysys.com/blog/wp-content/uploads/2018/03/query-resp-api-results-300x95.png 300w" sizes="(max-width: 674px) 100vw, 674px" /></a><p id="caption-attachment-2945" class="wp-caption-text">REST API QUERY IN SQL SERVER</p></div>
<p>&nbsp;</li>
<li>Also, the following query can be used when you need to use filters (Notice that we escaped single tick with double tick)</p><pre class="crayon-plain-tag">select * from OPENQUERY([RESTAPI-SV] , 'SELECT * FROM value where ContactTitle=''Owner''' )</pre><p>
</li>
<li>Store the data in a temporary table using the following query:</p><pre class="crayon-plain-tag">select * INTO #tmpcustomer from OPENQUERY([RESTAPI-SV] , 'SELECT * FROM value' )</pre><p>
</li>
<li>And now you can query and use the SQL table:</p><pre class="crayon-plain-tag">SELECT * FROM #tmpcustomer t</pre><p>
</li>
<li>You can also check the metadata, values and odata_next link:</p><pre class="crayon-plain-tag">select * from OPENQUERY([RESTAPI-SV] , 'SELECT * FROM $' )</pre><p>
&nbsp;</li>
</ol>
<h3>Call REST API in SQL Server (T-SQL Code) using Polybase (For SQL 2019 or higher)</h3>
<div class="content_block" id="custom_post_widget-8745"><div style="padding: 0px 0px 10px 0px;">

Once you configured data source in Gateway or in ODBC DSN Data Source, we can now Configure PolyBase to access external data in SQL Server.

</div>
<div style="padding: 0px 0px 10px 0px;">

PolyBase in SQL Server 2019 allows you to connect to ODBC-compatible data sources through the ODBC connector. For more details refer to <a href="https://docs.microsoft.com/en-us/sql/relational-databases/polybase/polybase-configure-odbc-generic?view=sql-server-ver15" target="_blank" rel="noopener">this link</a>.

</div>
<div style="padding: 0px 0px 10px 0px;">

If you haven't installed PolyBase, Please refer to this <a href="https://docs.microsoft.com/en-us/sql/relational-databases/polybase/polybase-installation?view=sql-server-ver15" target="_blank" rel="noopener" data-linktype="relative-path">PolyBase installation instruction</a>.

</div>
<ol>
 	<li>Assuming you have installed SQL Server, SSMS and Polybase. If not then get both SQL Server and SSMS for FREE from here: <a href="https://www.microsoft.com/en-us/sql-server/sql-server-editions-express">Get SQL Server Express</a> and  <a href="https://docs.microsoft.com/en-us/sql/ssms/download-sql-server-management-studio-ssms" target="_blank" rel="noopener">Get SSMS.</a></li>
 	<li>Open SSMS and connect to SQL Server.</li>
 	<li>After installing Polybase make sure you have an SSIS Catalog created. If you don't, create it in SSMS:
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-8843" src="https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-create-ssis-catalog-0.png" alt="" width="428" height="336" srcset="https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-create-ssis-catalog-0.png 428w, https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-create-ssis-catalog-0-300x236.png 300w" sizes="(max-width: 428px) 100vw, 428px" /></li>
 	<li>Configure the required settings:
<img loading="lazy" decoding="async" class="alignnone wp-image-8844 size-full" src="https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-create-ssis-catalog-e1583329508357.png" alt="" width="515" height="522" srcset="https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-create-ssis-catalog-e1583329508357.png 515w, https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-create-ssis-catalog-e1583329508357-296x300.png 296w" sizes="(max-width: 515px) 100vw, 515px" /></li>
 	<li>Also, make sure the SQL Server is configured to support TCP/IP protocol:
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-8845" src="https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-enable-tcp-ip-in-sql-server.png" alt="" width="644" height="349" srcset="https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-enable-tcp-ip-in-sql-server.png 644w, https://zappysys.com/blog/wp-content/uploads/2020/02/call-rest-api-in-polybase-enable-tcp-ip-in-sql-server-300x163.png 300w" sizes="(max-width: 644px) 100vw, 644px" /></li>
 	<li><strong>(optional)</strong> If in later steps you get a <em>Login</em> error, try connecting to your database using <em><strong>SQL Server Authentication</strong></em> instead of <em>Windows Authentication</em>.</li>
 	<li>Now, in SSMS open the new query window and select the desired database in which you want to call an external ODBC data source.</li>
 	<li>First, we need to create the MASTER KEY in the database where you are trying to create the External Data Source
<pre class="">--1
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'My$tr0ngP@$$w0rd';</pre>
</li>
 	<li>Now we need to create a database scoped credential for accessing the ODBC source in the database.
<pre class="">--2
CREATE DATABASE SCOPED CREDENTIAL SqlServerCredentials WITH IDENTITY = 'username', Secret = 'password';</pre>
</li>
 	<li>Now go to our configured ZS Driver data source which one we created using Gateway or ODBC DSN Data Source and copy the connection string from there.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/12/copy-connection-string-of-odbc-datasource-for-office-365-e1547488424263.png" target="_blank" rel="noopener">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2018/12/copy-connection-string-of-odbc-datasource-for-office-365-e1547488424263.png" alt="" />
</a>
<p class="wp-caption-text">Copy Connection String from the ZS Driver</p>

</div></li>
 	<li>Now Using that ZS Driver connection string and credentials we need to create the external data source.
<pre class=""><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">EXTERNAL</span> <span class="hljs-keyword">DATA</span> <span class="hljs-keyword">SOURCE</span> external_data_source_name
<span class="hljs-keyword">WITH</span> (LOCATION = odbc://&lt;ODBC <span class="hljs-keyword">server</span> address&gt;[:&lt;port&gt;],
CONNECTION_OPTIONS = <span class="hljs-string">'&lt;zs-driver-conection-string&gt;;
ServerNode = &lt;name of server  address&gt;:&lt;Port&gt;'</span>,
CREDENTIAL = &lt;credential_name&gt; );</pre>
So that our query looks like this, we need to use the same credentials name which one we created.
<pre class="">--3
CREATE EXTERNAL DATA SOURCE [ZappySys_Ext_CSV_Data_source] WITH (LOCATION = N'ODBC://127.0.0.1:5000', CREDENTIAL = [SqlServerCredentials],
CONNECTION_OPTIONS= 'DRIVER={ZappySys CSV Driver};DataPath='E:\zsTemp\Mydata.csv'')
</pre>
Or If you have created the ODBC System DSN Data Source
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2020/02/odbc-system-dsn-zs-csv-driver.png" target="_blank" rel="noopener">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2020/02/odbc-system-dsn-zs-csv-driver.png" alt="" />
</a>
<p class="wp-caption-text">ODBC System DSN : ZappySys CSV Driver</p>

</div>
We can pass the DSN Name also in the query instead of Zs driver connection string, in that case, we need to query like below to create the external data source
<pre class="">--3
CREATE EXTERNAL DATA SOURCE [ZappySys_Ext_CSV_Data_source] WITH (LOCATION = N'ODBC://127.0.0.1:5000', CREDENTIAL = [SqlServerCredentials],
CONNECTION_OPTIONS= 'DSN=zsDSN_MyCSVDriver')
</pre>
</li>
 	<li>Furthermore, we need to create the External Data Table for that external data source.
<pre class="">--4
CREATE EXTERNAL TABLE extTblPersons (
ID bigint NULL,
Name nvarchar(250) NULL
)
WITH (
LOCATION='_root_',
DATA_SOURCE = [ZappySys_Ext_CSV_Data_source] ,
)</pre>
For Location value, we need to pass the table name, from the ZS Driver Preview Tab we can download get the table name.
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2020/02/odbc-preview-tab-table-list.png" target="_blank" rel="noopener">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2020/02/odbc-preview-tab-table-list.png" alt="" />
</a>
<p class="wp-caption-text">ZS Driver Query Preview -Table List</p>

</div></li>
 	<li>That's it now execute the query using that external data table, it will retrieve the data from the external ODBC Data source. So here it will read the data from the Mydata.csv csv file and load the query data in the SQL Server.
<pre class="">--5
Select * From extTblPersons</pre>
<div class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2020/02/sql-server-query-result.png" target="_blank" rel="noopener">
<img decoding="async" src="https://zappysys.com/blog/wp-content/uploads/2020/02/sql-server-query-result.png" alt="" />
</a>
<p class="wp-caption-text">SQL Server Query Result</p>

</div></li>
</ol></div>
<h2>How to use Dynamic SQL with parameters</h2>
<p>So far we saw how to use OPENQUERY statement with a static SQL query. Now let&#8217;s look at the dynamic Query approach to Read REST API data and Load into SQL Table. For Dynamic SQL you have to use EXEC rather than OPENQUERY.</p><pre class="crayon-plain-tag">--MSDTC option must be off for INSERT + EXEC pattern (Find Linked Server Properties | Server Options | Enable Promotion of Distributed Transaction - [Set to false]
--OR-- run via code like below
--EXEC master.dbo.sp_serveroption 'MyLinkedServer', 'remote proc transaction promotion', false;

declare @tbl nvarchar(100) = 'value'
--Just output the query data (no insert)
EXEC('select col1,col2 from ' + @tbl) AT [MyLinkedServer]

--Load into table (dont output)
insert into _tmp_invoices(col1,col2) 
EXEC('select col1,col2 from ' + @tbl) AT [MyLinkedServer]

--We recommend using column names in the list rather than * (all) to avoid metdata issue
--Use Data Source &gt; Preview UI &gt; Table dropdown to generate column names</pre><p>
&nbsp;</p>
<h2>How to parameterize API calls in SQL Server</h2>
<p>Now you know how to write simple SQL queries to fetch data from API. In real world you will have a need to pass parameters to your API. You can pass parameters to your API following ways.  Notice that how we have escaped single tick. In this example we have passed Header, Body and URL using Dynamic approach. In your case you may need to pass only one way (e.g. Pass parameter via URL only)</p><pre class="crayon-plain-tag">declare @url varchar(100)='http://httpbin.org/post' 
declare @body varchar(100)='{id:1,notes:"Line1\r\nLine2"}'
declare @header varchar(100)='Content-Type:text/plain||x-hdr1:AAA'

declare @sql varchar(1000)
declare @sqlForLs  varchar(1000) = 
'SELECT * FROM $
WITH  (
SRC='''+ replace(@url,'''', '''''')  +''' ,
METHOD=''POST'' ,
HEADER='''+ replace(@header,'''', '''''')  +''' ,
BODY='''+ replace(@body,'''', '''''')  +''' 
)'
 
set @sql = 'SELECT * into #tmp from OPENQUERY(LS,''' + replace(@sqlForLs,'''', '''''') + ''')'
print @sql

EXECUTE(@sql);</pre><p>
&nbsp;</p>
<h2>How to Import JSON File to SQL Server (Single or Multiple)</h2>
<p>Not only you can query REST API in SQL Server but also you can query a JSON file. The steps are all the same except in one step. Instead of specifying a URL in the ZappySys ODBC driver (see Add the ZappySys driver in the Windows ODBC Administrator section, step 7) and specify the <strong>file path</strong> and set the format to <strong>Default:</strong></p>
<div id="attachment_2953" style="width: 621px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/How-to-import-REST-API-in-SQL-Server-2.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2953" class="size-full wp-image-2953" src="https://zappysys.com/blog/wp-content/uploads/2018/03/How-to-import-REST-API-in-SQL-Server-2.png" alt="JSON file properties" width="611" height="595" /></a><p id="caption-attachment-2953" class="wp-caption-text">Add properties JSON file</p></div>
<p>If you dont want to hard code file name in the DSN then you can also use following Query syntax to specify URL or File Path inside SQL Query</p><pre class="crayon-plain-tag">select * into #tmp from OPENQUERY([JSON-SV], 'SELECT * FROM value WITH (SRC=''C:\test\cust2012.json'')' )</pre><p>
<h2>How to load multiple JSON files into SQL Server Table</h2>
<p>Let&#8217;s say that you have multiple JSON files in a folder (similar structure). The file names are customer_2012.json, customer_2013.json, customer_2014.json and they are all in the same folder. Is it possible to query all of them in SQL Server without any extra looping code?</p>
<p>The answer is yes. You just need to create the linked server to a single JSON file and then run this query (JSON-SV is the name of the linked server):</p><pre class="crayon-plain-tag">select * into #tmp from OPENQUERY([JSON-SV], 'SELECT * FROM value WITH (SRC=''C:\test\cust*.json'')' )</pre><p>
We are just using this code:</p><pre class="crayon-plain-tag">(SRC=''C:\test\cust*.json'')' )</pre><p>
SRC means source and it will search all the files with json extension starting with the word &#8220;cust&#8221;.</p>
<h2>How to read and parse JSON string in T-SQL</h2>
<p>In SQL Server 2016 and later, it is possible to read JSON data. However in older versions, it was not possible. The following example will show how to parse JSON data using a Linked Server named JSON-SV.</p>
<ol>
<li style="list-style-type: none;">
<ol>
<li>We will first store JSON values in a SQL Server table in a column named MyData:<br />
<pre class="crayon-plain-tag">create table #tmp(MyData nvarchar(max))

insert into #tmp values(
'{ 
rows:[ 
{id:1, name:"Sam''s Club"}, 
{id:2, name:"Walmart"}, 
{id:3, name: "Facebook"} 
]
}')</pre>
</li>
<li>We just created a temporary table named tmp and in the column MyData, we stored JSON values. In the next step, we will store the values of the temporary table in a variable named json and store and parse the values en the variable sql:<br />
<pre class="crayon-plain-tag">declare @json nvarchar(max)
declare @sql nvarchar(max)

select @json = MyData from #tmp


set @sql='select * from OPENQUERY([JSON-SV] , ''SELECT * FROM rows WITH
(DATA=@'''''+ Replace(@json ,'''','''''''''') +''''')'' );'
print(@sql)
execute(@sql)</pre>
</li>
<li>If everything is OK, you will be able to see the JSON values parsed in a nice table format:
<div id="attachment_2960" style="width: 200px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/parse-json-sql-server.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-2960" class="size-full wp-image-2960" src="https://zappysys.com/blog/wp-content/uploads/2018/03/parse-json-sql-server.png" alt="Parse JSON values" width="190" height="111" /></a><p id="caption-attachment-2960" class="wp-caption-text">JSON values parsed</p></div></li>
</ol>
</li>
</ol>
<h2>How to Call REST API from a SQL Stored Procedure</h2>
<p>How can we call REST API using a stored procedure? We need to use dynamic queries to pass parameters. The following example will run a query where the city is specified in a variable.</p>
<ol>
<li>We will create the stored procedure first:<br />
<pre class="crayon-plain-tag">CREATE PROCEDURE getcity 
@City NVARCHAR(50) 
AS 
DECLARE @sql NVARCHAR(500)='select * from OPENQUERY([RESTAPI-SV] , 
''SELECT * FROM value where City=''''' + @City + ''''''')' 
EXECUTE(@sql)</pre>
</li>
<li>The stored procedure name is getcity. We will call the RESTAPI-SV that calls the REST API and pass the parameter City in the query. We finally execute the query stored in the variable using the Execute statement.</li>
<li>Finally, we just invoke the stored procedure:<br />
<pre class="crayon-plain-tag">EXECUTE getcity @City = N'Berlin'</pre>
The query will display all the data with the city equal to Berlin.</li>
</ol>
<h2>How to POST data to REST API in SQL Server (Send data to URL)</h2>
<p>The following example shows how to POST data to API service where data is coming from an embedded string in SQL Server using a Linked Server. I am assuming that you already created a linked server following previews steps explained before.</p>
<h3>POST data to URL (embedded Body)</h3>
<p>In SSMS run this query:</p><pre class="crayon-plain-tag">select * from OPENQUERY([RESTAPI-SV] , 'SELECT * FROM $ 
WITH (
 METHOD=''POST''
,HEADER=''Content-Type: application/json || x-hdr1: AAA''
,SRC=''http://httpbin.org/post''
,BODY=''{ id:2,  notes2:"Line1\r\nLine2" }''
)' 
)</pre><p>
The query will invoke the Linked Server for REST API, created before and use the POST Method with the embedded strings.</p>
<h3>POST data to URL (read body from file)</h3>
<p>Here is an example to POST data to URL where Body is read from Local file. Notice two additional attributes in below.  We set IsMultiPart=true and also Body has @ symbol before file path.</p><pre class="crayon-plain-tag">select * from OPENQUERY([RESTAPI-SV] , 'SELECT * FROM $ 
WITH (
 METHOD=''POST''
,HEADER=''Content-Type: application/json || x-hdr1: AAA''
,SRC=''http://httpbin.org/post''
,BODY=''@c:\data\api_call_body.json''
,IsMultiPart='True'
)' 
)</pre><p>
<h3>Avoiding errors with POST / PUT / DELETE  requests to create / modify /delete data</h3>
<p>There will be a time you may get error when you issue POST requests because same request sent multiple times and duplicate records got created. To avoid such situation <a href="https://zappysys.com/blog/caching-metadata-odbc-drivers-performance/" target="_blank" rel="noopener">refer to this article</a> (Read Handling POST request section)</p>
<h2>Pagination Concepts for REST API / SOAP XML  in SQL Server</h2>
<div class="content_block" id="custom_post_widget-3892"><div style="margin-bottom: 1em;">Even we set up ODBC Data Source to get the data, it may not be enough. Usually, if you are getting a huge data set from API provider, it won't give it to you in one HTTP response. Instead, it gives back only a subset of data and provides a mechanism for data pagination. The good news is that <em>ZappySys ODBC Driver</em> includes many options to cover virtually any pagination method.</div>
<div><span style="font-size: 16px;">Below you will find a few examples of API pagination. If you need something more sophisticated check the below link (the article was written for SSIS PowerPack but UI options and concepts apply to ODBC Driver too):</span></div>
<div style="margin-bottom: 1em;"><a href="https://zappysys.com/blog/ssis-rest-api-looping-until-no-more-pages-found/" target="_blank" rel="noopener">https://zappysys.com/blog/ssis-rest-api-looping-until-no-more-pages-found/</a></div>
<h3>Paginate by Response Attribute</h3>
This example shows how to paginate API calls where you need to paginate until the last page detected. In this example, next page is indicated by some attribute called nextlink (found in response). If this attribute is missing or null then it stops fetching the next page.
<pre class="lang:tsql decode:true codeblock">SELECT * FROM $
WITH(
SRC=@'https://zappysys.com/downloads/files/test/pagination_nextlink_inarray_1.json'
,NextUrlAttributeOrExpr = '$.nextlink'  --keep reading until this attribute is missing. If attribute name contains dot then use brackets like this $.['my.attr.name']
)</pre>
<h3>Paginate by URL Parameter (Loop until certain StatusCode)</h3>
This example shows how to paginate API calls where you need to pass page number via URL. The driver keeps incrementing page number and calls next URL until the last page detected (401 error). There are few ways to indicate the last page (e.g. By status code, By row count, By response size). If you don't specify end detection then it will use the default (i.e. No records found).
<pre class="lang:tsql decode:true codeblock">SELECT * FROM $
WITH (
SRC=@'https://zappysys.com/downloads/files/test/page-xml.aspx?page=1&amp;mode=DetectBasedOnResponseStatusCode'
,PagingMode='ByUrlParameter'
,PagingByUrlAttributeName='page'
,PagingByUrlEndStrategy='DetectBasedOnResponseStatusCode'
,PagingByUrlCheckResponseStatusCode=401
,IncrementBy=1
)</pre>
<h3>Paginate by URL Path (Loop until no record)</h3>
This example shows how to paginate API calls where you need to pass page number via URL Path. The driver keeps incrementing page number and calls next URL until the last page is detected. There are few ways to indicate the last page (e.g. By status code, By row count, By response size). If you don't specify end detection then it will use the default (i.e. No records found).
<pre class="lang:tsql decode:true codeblock">SELECT * FROM $
WITH (
SRC=@'https://zappysys.com/downloads/files/test/cust-&lt;%page%&gt;.xml'
,PagingMode='ByUrlPath'
,PagingByUrlAttributeName='&lt;%page%&gt;'
,PagingByUrlEndStrategy='DetectBasedOnRecordCount'
,IncrementBy=1
)</pre>
<h3>Paginate by Header Link (RFC 5988)</h3>
API like GitHub / Wordpress use Next link in Headers (<a href="https://tools.ietf.org/html/rfc5988" target="_blank" rel="noopener">RFC 5988</a>)
<pre class="lang:default decode:true ">SELECT * FROM $
LIMIT 25
WITH(
	 Src='https://wordpress.org/news/wp-json/wp/v2/categories?per_page=10'
	,PagingMode='ByResponseHeaderRfc5988'
	,WaitTimeMs='200' --//wait 200 ms after each request
)</pre>
&nbsp;</div>
<h2>Error Handling for REST API / SOAP XML in SQL Server</h2>
<div class="content_block" id="custom_post_widget-3894">Sometimes errors occur... they just do and there is nothing you can do! Or can you? Actually, in ODBC PowerPack you can handle them in two ways.
<h3>METHOD 1 - Using Error Handling Options</h3>
<img loading="lazy" decoding="async" class="alignnone size-full wp-image-3949" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-api-error-handling-1.png" alt="" width="668" height="702" />
<h4>When to use?</h4>
You may want to use them when your source is a resource located on the Internet; e.g. a file on a website, a file on an FTP server or just a plain API HTTP response. By default, when a remote server returns an error, data retrieval is stopped, an error is raised and no data is given back to you. This might not be always desirable.
<h4>Scenario 1</h4>
Imagine a scenario, that there is a web server which each day at 12 AM releases a new JSON file with that day's date as filename, e.g. <span style="text-decoration: underline;"><em>http://www.some-server.com/data/2018-06-20.json</em></span>. And, of course, you want to download it and use it daily in your Power BI report. But you have a problem: Power BI report data sources are refreshed each hour and you may get <a href="https://en.wikipedia.org/wiki/HTTP_404" target="_blank" rel="noopener">HTTP 404 status code</a> (no file was found) when a file is not released yet. Which consequentially means other data sources won't be updated as well and you will see old and cached data on the report. That's where you could use <strong><span class="lang:default highlight:0 decode:true crayon-inline">Continue on any error</span></strong> or <strong><span class="lang:default highlight:0 decode:true crayon-inline">Continue when Url is invalid or missing (404 Errors)</span></strong> to avoid an error being raised and let other data sources to be updated.
<h4>Scenario 2</h4>
Another scenario is when you expect a web server to raise some kind of HTTP error when accessing a URL. You don't want ODBC Data Source to raise an error but instead, you want to get response data. That's where you can use <strong><span class="lang:default highlight:0 decode:true crayon-inline">Continue on any error</span></strong> or alike together with  <strong><span class="lang:default highlight:0 decode:true crayon-inline">Get response data on error</span></strong> to continue on an error and get the data:

<img loading="lazy" decoding="async" class="alignnone wp-image-3961 size-full" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-powerpack-get-response-data-on-error.png" alt="" width="547" height="235" srcset="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-powerpack-get-response-data-on-error.png 547w, https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-powerpack-get-response-data-on-error-300x129.png 300w" sizes="(max-width: 547px) 100vw, 547px" />
<h3>METHOD 2 - Using Connection [Retry Settings]</h3>
Another scenario you may run into is a buggy web server. You ask it to give you some file or data and it, like a snotty kid, just doesn't give it to you! You have to ask twice or thrice before it does its job. If that's the case, you have to retry HTTP requests using <em>Connection</em>:

<img loading="lazy" decoding="async" class="alignnone wp-image-3963 size-full" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-api-error-handling-3.png" alt="" width="671" height="572" /></div>
<h2>OAuth / HTTP Connection in SQL Server</h2>
<div class="content_block" id="custom_post_widget-3896"><div style="margin-bottom: 1em;">If you need to authenticate or authorize your user to access a web resource, you will need to use one of the <em>Connections:</em></div>
<ul>
 	<li>HTTP</li>
 	<li>OAuth</li>
</ul>
<img loading="lazy" decoding="async" class="wp-image-4078 size-full" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-powerpack-authentication-authorization-e1529337108252.png" alt="ZappySys XML Driver - HTTP and OAuth Connection Types" width="577" height="302" srcset="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-powerpack-authentication-authorization-e1529337108252.png 577w, https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-powerpack-authentication-authorization-e1529337108252-300x157.png 300w" sizes="(max-width: 577px) 100vw, 577px" />
<h3>HTTP Connection</h3>
<div style="margin-bottom: 1em;">Use <em>HTTP Connection</em> for simple Windows, Basic, NTLM or Kerberos authentication. Just fill in a username and a password and you are good to go!</div>
<div style="margin-bottom: 1em;">You can also use <em>HTTP Connection</em> for more sophisticated authentication like:</div>
<ul>
 	<li><strong>SOAP WSS</strong> (when accessing a SOAP WebService)</li>
 	<li><strong>Static Token / API Key</strong> (when need to pass an API key in HTTP header)</li>
 	<li><strong>Dynamic Token</strong> (same as Static Token method except that each time you need to log in and retrieve a fresh API key)</li>
 	<li><strong>JWT Token</strong> (As per RFC 7519)</li>
</ul>
<img loading="lazy" decoding="async" class="alignnone wp-image-4091 size-full" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-api-connection-type-1.png" alt="" width="622" height="570" />
<h3>OAuth</h3>
If you are trying to access REST API resource, it is a huge chance, you will need to use <em>OAuth Connection</em>. <a href="https://zappysys.com/blog/rest-api-authentication-with-oauth-2-0-using-ssis/" target="_blank" rel="noopener">Read this article</a> to understand how OAuth authentication and authorization works and how to use it (article originally was written for <a href="https://zappysys.com/products/ssis-powerpack/" target="_blank" rel="noopener">SSIS PowerPack</a>, but the concepts and UI stay the same): <br/>
<a href="https://zappysys.com/blog/rest-api-authentication-with-oauth-2-0-using-ssis/" target="_blank" rel="noopener">https://zappysys.com/blog/rest-api-authentication-with-oauth-2-0-using-ssis/</a>
<img loading="lazy" decoding="async" class="alignnone size-full" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-api-connection-type-2.png" width="721" height="708" /></div>
<h2>Performance Tips for REST API / XML SOAP Calls</h2>
<div class="content_block" id="custom_post_widget-4455">While calling APIs you may face some performance issues. There are a few tips you can consider to speed up things.
<h4><span style="font-size: 14pt;"><strong>Use Server-side filtering if possible in URL or Body Parameters</strong></span></h4>
Many API supports filtering your data by URL parameters or via Body. Whenever possible try to use such features.  Here is an example of <a href="http://www.odata.org/getting-started/basic-tutorial/" target="_blank" rel="noopener">odata API</a>, In the below query the first query is faster than the second query because in the first query we filter at the server.
<pre class="lang:tsql decode:true">SELECT * FROM value
WITH(
	 Src='https://services.odata.org/V3/Northwind/Northwind.svc/Customers?$format=json&amp;$filter=Country eq ''USA'''
	,DataFormat='Odata'
)

-- Slow query - Client-side filtering
SELECT * FROM value
WHERE Country ='USA'
WITH(
	 Src='https://services.odata.org/V3/Northwind/Northwind.svc/Customers?$format=json'
	,DataFormat='Odata'
)</pre>
<h4><span style="font-size: 14pt;"><strong>Avoid Special features in SQL Query (e.g. WHERE, Group By, Order By)</strong></span></h4>
ZappySys API engine triggers client-side processing if special features are used in Query. Following SQL Features will trigger Client-Side processing which is several times slower than server-side processing. So always try to use simple query (Select col1, col2 .... from mytable )
<ul>
 	<li>WHERE Clause</li>
 	<li>GROUP BY Clause</li>
 	<li>HAVING Clause</li>
 	<li>ORDER BY</li>
 	<li>FUNCTIONS (e.g. Math, String, DateTime, Regex... )</li>
</ul>
LIMIT clause does not trigger client-side processing.
<h4><span style="font-size: 14pt;"><strong>Consider using pre-generated Metadata / Cache File</strong></span></h4>
Use META option in WITH Clause to use static metadata (Pre-Generated)There are two more options to speedup query processing time. Check <a href="https://zappysys.com/blog/caching-metadata-odbc-drivers-performance/" target="_blank" rel="noopener">this article</a> for details.
<ol>
 	<li>
<pre class="lang:default decode:true">select * from value WITH( meta='c:\temp\meta.txt' )
--OR--
select * from value WITH( meta='my-meta-name' )
--OR--
select * from value WITH( meta='[ {"Name": "col1",&amp;nbsp;"Type": "String", Length: 100},&amp;nbsp;{"Name": "col2",&amp;nbsp;"Type": "Int32"} ...... ]' )</pre>
</li>
 	<li>Enable Data Caching Options (Found on <strong>Property Grid</strong> &gt; <strong>Advanced</strong> Mode Only )</li>
</ol>
<h4><span style="font-size: 14pt;"><strong>Consider using Metadata / Data Caching Option</strong></span></h4>
ZappySys API drivers support Caching Metadata and Data rows to speed up query processing. If your data doesn't change often then you can enable this option to speed up processing significantly.

Check <a href="https://zappysys.com/blog/caching-metadata-odbc-drivers-performance/" target="_blank" rel="noopener">this article</a> for details how to enable Data cache / metadata cache feature for datasource level or query level.

To define cache option at query level you can use like below.
<pre class="">SELECT * FROM $
WITH 
(  SRC='https://myhost.com/some-api'
  ,CachingMode='All'  --cache metadata and data rows both
  ,CacheStorage='File' --or Memory
  ,CacheFileLocation='c:\temp\myquery.cache'
  ,CacheEntryTtl=300 --cache for 300 seconds
)
</pre>
&nbsp;

&nbsp;
<h4><strong><span style="font-size: 14pt;">Use --FAST Option to enable Stream Mode</span></strong></h4>
ZappySys JSON / XML drivers support <strong>--FAST</strong> suffix for Filter. By using this suffix after Filter driver enables Stream Mode, <a href="https://zappysys.com/blog/caching-metadata-odbc-drivers-performance/#Reading_Large_Files_Streaming_Mode_for_XML_JSON" target="_blank" rel="noopener">Read this article</a> to understand how this works.
<pre class="lang:default decode:true">SELECT * FROM $ 
LIMIT 10 --//add this just to test how fast you can get 10 rows
WITH(
  Filter='$.LargeArray[*]--FAST' --//Adding --FAST option turn on STREAM mode (large files)
 ,SRC='https://zappysys.com/downloads/files/test/large_file_100k_largearray_prop.json.gz'
 --,SRC='c:\data\large_file.json.gz'
 ,IncludeParentColumns='False'  --//This Must be OFF for STREAM mode (read very large files)
 ,FileCompressionType='GZip' --Zip or None (Zip format only available for Local files)
)</pre>
&nbsp;</div>
<h2>Other Considerations for Calling Web API in SQL Server</h2>
<div class="content_block" id="custom_post_widget-3901">There are few settings you can coder while calling Web API
<h3><strong>API Limit / Throttling</strong></h3>
While calling public API or other external web services one important aspect you have to check,  how many requests are allowed by your API. Especially when you use API pagination options to pull many records you have to slow down based on API limits. For example, your API may allow you only 5 requests per second. Use Throttling Tab on Driver UI to set delay after each request.
<h3><strong>2D Array Transformation</strong></h3>
If you are using JSON or XML API Driver then possible you may have to transform your data using 2D array transformation feature. <a href="https://zappysys.com/blog/parse-multi-dimensional-json-array-ssis/" target="_blank" rel="noopener">Check this link</a> for more information.

&nbsp;</div>
<h2>Calling XML SOAP Web Service in SQL Server</h2>
<p>So far we have looked at examples to consume data using JSON driver. Now let&#8217;s look at an example, to call XML SOAP Web Service.</p>
<div class="content_block" id="custom_post_widget-3870">To call SOAP API you need to know Request XML Body Structure. If you are not sure how to create SOAP Request body then no worries. <a href="https://zappysys.com/blog/calling-soap-web-service-in-ssis-xml-source/" target="_blank" rel="noopener">Check this article</a> to learn how to generate SOAP Request body using the Free tool <a href="https://www.soapui.org/downloads/latest-release.html" target="_blank" rel="noopener">SoapUI</a>. Basically, you have to use SoapUI to generate Request XML and after that, you can replace parameters as needed in the generated body.
<h3>What is SOAP Web Service?</h3>
If you are new to SOAP Web Service sometimes referred as XML Web Service then please read some concept about SOAP Web service standard <a href="https://msdn.microsoft.com/en-us/library/ms996507.aspx?f=255&amp;MSPPError=-2147217396" target="_blank" rel="noopener">from this link</a>

There are two important aspects in SOAP Web service.
<ol>
 	<li>Getting WSDL file or URL</li>
 	<li>Knowing exact Web Service URL</li>
</ol>
<h3>What is WSDL</h3>
In very simple term WSDL (often pronounced as whiz-dull) is nothing but a document which describes Service metadata (e.g. Functions you can call, Request parameters, response structure etc). Some service simply give you WSDL as xml file you can download on local machine and then analyze or sometimes you may get direct URL (e.g. http://api.mycompany.com/hr-soap-service/?wsdl )
<h3>Example SQL Query for SOAP API call using ZappySys XML Driver</h3>
Here is an example SQL query you can write to call SOAP API. If you not sure about many details then check next few sections on how to use XML Driver User Interface to build desired SQL query to POST data to XML SOAP Web Service without any coding.
<pre class="lang:tsql decode:true">SELECT * FROM $
WITH(
	 Src='http://www.holidaywebservice.com/HolidayService_v2/HolidayService2.asmx'
	,DataConnectionType='HTTP'
	,CredentialType='Basic' --OR SoapWss
	,SoapWssPasswordType='PasswordText'
	,UserName='myuser'
	,Password='pass$$w123'
	,Filter='$.soap:Envelope.soap:Body.GetHolidaysAvailableResponse.GetHolidaysAvailableResult.HolidayCode[*]'
	,ElementsToTreatAsArray='HolidayCode'	
	,RequestMethod='POST'	
	,Header='Content-Type: text/xml;charset=UTF-8 || SOAPAction: "http://www.holidaywebservice.com/HolidayService_v2/GetHolidaysAvailable"'
	,RequestData='
&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:hol="http://www.holidaywebservice.com/HolidayService_v2/"&gt;
   &lt;soapenv:Header/&gt;
   &lt;soapenv:Body&gt;
      &lt;hol:GetHolidaysAvailable&gt;
         &lt;!--type: Country - enumeration: [Canada,GreatBritain,IrelandNorthern,IrelandRepublicOf,Scotland,UnitedStates]--&gt;
         &lt;hol:countryCode&gt;UnitedStates&lt;/hol:countryCode&gt;
      &lt;/hol:GetHolidaysAvailable&gt;
   &lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;'
)</pre>
Now let's look at steps to create SQL query to call SOAP API. Later we will see how to generate code for your desired programming language (e.g. C# or SQL Server)
<h3>Video Tutorial - Introduction to SOAP Web Service and SoapUI tool</h3>
Before we dive into details about calling SOAP API using ZappySys XML Driver, lets first understand what is SOAP API and how to create SOAP requests using SoapUI tool. You will learn more about this process in the later section. The video contains some fragment about using SOAP API in SSIS but just ignore that part because we will be calling Soap API using ZappySys ODBC Driver rather than SSIS Components.

&nbsp;

<iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/d_x5bgGjg0Y?rel=0&amp;showinfo=0" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen="allowfullscreen" data-mce-fragment="1"></iframe>
<h3>Using SoapUI to test SOAP API call / Create Request Body XML</h3>
Assuming you have downloaded and installed <a href="https://www.soapui.org/downloads/latest-release.html" target="_blank" rel="noopener">SoapUI from here</a>, now we are ready to use WSDL for your SOAP Web Service Calls. If you do not have WSDL file or URL handy then contact your API provider (sometimes you just have to add <strong>?wsdl </strong>at the end of your Service URL to get WSDL so try that. Example: http://mycompany/myservice?wsdl ).

If you don't know what is WSDL then in short, WSDL is <strong>Web service Description Language</strong> (i.e. XML file which describes your SOAP Service). WSDL helps to craft SOAP API request Body for ZappySys XML Driver. So Let's get started.
<ol>
 	<li>Open SoapUI and click SOAP button to create new SOAP Project</li>
 	<li>Enter WSDL URL or File Path of WSDLFor example WSDL for our sample service can be accessed via this URL
<pre class="lang:default highlight:0 decode:true">http://www.dneonline.com/calculator.asmx?wsdl</pre>
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/calling-soap-api-import-wsdl-new-soapui-project.png"><img loading="lazy" decoding="async" class="size-full wp-image-3871" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-14.png" alt="Create new SOAP API Project in SoapUI tool for SOAP API Testing" width="486" height="349" /></a>
<div style="margin-bottom: 1em;">Create new SOAP API Project in SoapUI tool for SOAP API Testing</div></li>
 	<li>Once WSDL is loaded you will see possible operations you can call for your SOAP Web Service.</li>
 	<li>If your web service requires credentials then you have to configure it. There are two common credential types for public services (<strong>SOAP WSS</strong> or <strong>BASIC</strong> )
<ol>
 	<li>
<div style="margin-bottom: 1em;">To use <strong>SOAP WSS Credentials</strong> select request node and enter UserId, Password, and <strong>WSS-PasswordType</strong> (PasswordText or PasswordHash)</div>
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/calling-soap-api-pass-soap-wss-credentials-userid-password.png"><img loading="lazy" decoding="async" class="size-full wp-image-3872 alignnone" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-2.png" alt="Configure SOAP WSS Credentials for SoapUI (SOAP API Testing Tool)" width="294" height="544" /></a>
<div style="display: block;">Configure SOAP WSS Credentials for SoapUI (SOAP API Testing Tool)</div></li>
 	<li>To use <strong>BASIC Auth</strong> Credentials select request node and double-click it. At the bottom click on Auth (Basic) and From Authorization dropdown click Add New and Select Basic.<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/calling-soap-api-pass-basic-authentication-userid-password.png"><img loading="lazy" decoding="async" class="size-full wp-image-3873" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-2.png" alt="Configure Basic Authorization for SoapUI (SOAP API Testing Tool)" width="616" height="653" /></a>
<div style="margin-bottom: 1em;">Configure Basic Authorization for SoapUI (SOAP API Testing Tool)</div></li>
</ol>
</li>
 	<li>Now you can test your request first Double-click on the request node to open request editor.</li>
 	<li>Change necessary parameters, remove optional or unwanted parameters. If you want to regenerate request you can click on <strong>Recreate default request toolbar icon</strong>.
<a href="https://zappysys.com/blog/wp-content/uploads/2016/06/create-soap-request-with-optional-parameters-soapui.png"><img loading="lazy" decoding="async" class="size-full wp-image-2812" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-4.png" alt="Create SOAP Request XML (With Optional Parameters)" width="807" height="315" /></a>
<div style="margin-bottom: 1em;">Create SOAP Request XML (With Optional Parameters)</div></li>
 	<li>Once your SOAP Request XML is ready, <strong>Click the Play button</strong> in the toolbar to execute SOAP API Request and Response will appear in Right side panel.
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/soapui-test-soap-api-request-response-edit-xml-body.png"><img loading="lazy" decoding="async" class="size-full wp-image-3874" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-5.png" alt="Test SOAP API using SoapUI Tool (Change Default XML Body / Parameters, Execute and See Response)" width="1216" height="511" /></a>
Test SOAP API using SoapUI Tool (Change Default XML Body / Parameters, Execute and See Response)</li>
</ol>
<h3>Create DSN using ZappySys XML Driver to call SOAP API</h3>
Once you have tested your SOAP API in SoapUI tool, we are ready to use ZappySys XML driver to call SOAP API in your preferred BI tool or Programming language.
<ol>
 	<li>First open <strong>ODBC Data Sources</strong> (search ODBC in your start menu or go under ZappySys &gt; ODBC PowerPack &gt; <strong>ODBC 64 bit</strong>)</li>
 	<li>Goto <strong>System DSN</strong> Tab (or User DSN which is not used by Service account)</li>
 	<li>Click <strong>Add</strong> and Select ZappySys XML Driver
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/zappysys-odbc-xml-soap-api-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3875" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-6.png" alt="ZappySys ODBC Driver for XML / SOAP API" width="593" height="459" /></a>
ZappySys ODBC Driver for XML / SOAP API</li>
 	<li>Configure API URL, Request Method and Request Body as below
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/calling-soap-web-service-zappysys-xml-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3876" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-7.png" alt="ZappySys XML Driver - Calling SOAP API - Configure URL, Method, Body" width="916" height="874" /></a>
ZappySys XML Driver - Calling SOAP API - Configure URL, Method, Body</li>
 	<li><strong>(This step is Optional)</strong> If your SOAP API requires credentials then Select Connection Type to HTTP and configure as below.
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/soap-api-call-credential-basic-soap-wss-zappysys-xml-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3877" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-8.png" alt="ZappySys XML Driver - Configure SOAP WSS Credentials or Basic Authorization (Userid, Password)" width="564" height="483" /></a>
<div style="display: block;">ZappySys XML Driver - Configure SOAP WSS Credentials or Basic Authorization (Userid, Password)</div></li>
 	<li>Configure-Request Headers as below (You can get it from Request &gt; Raw tab from SoapUI after you test the request by clicking the Play button)
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/set-soap-api-request-headers-zappysys-xml-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3881" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-9.png" alt="Configure SOAP API Request Headers - ZappySys XML Driver" width="1009" height="747" /></a>
Configure SOAP API Request Headers - ZappySys XML Driver</li>
 	<li>Once credentials entered you can select Filter to extract data from the desired node. Make sure to select array node (see special icon) or select the node which contains all necessary columns if you don't have array node.
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/soap-api-query-select-filter-zappysys-xml-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3882" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-10.png" alt="Select Filter - Extract data from nested XML / SOAP API Response (Denormalize Hierarchy)" width="809" height="594" /></a>
Select Filter - Extract data from nested XML / SOAP API Response (Denormalize Hierarchy)</li>
 	<li>If prompted select yes to treat selected node as Array (This is helpful when you expect one or more record for selected node)
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/xml-api-array-handling-zappysys-xml-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3883" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-11.png" alt="Treat selected node as XML Array Option for SOAP API Response XML" width="655" height="572" /></a>
Treat selected node as XML Array Option for SOAP API Response XML</li>
</ol>
<h3>Preview SOAP API Response / Generate SQL Code for SOAP API Call</h3>
Once you configure settings for XML Driver now you can preview data or generate example code for desired language (e.g. C#, Python, Java, SQL Server).

Go to Preview tab and you will see default query generated based on settings you entered in previous sections. Attributes listed in WITH clause are optional. If you omit attribute in WITH clause it will use it from Properties tab.
<h3>Preview Data</h3>
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/calling-soap-web-service-zappysys-xml-api-driver.png"><img loading="lazy" decoding="async" class="size-full wp-image-3884" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-12.png" alt="Preview SOAP API Response in ZappySys XML Driver" width="808" height="780" /></a>
Preview SOAP API Response in ZappySys XML Driver
<h3>Generate Code Option</h3>
<a href="https://zappysys.com/blog/wp-content/uploads/2018/06/zappysys-driver-code-generator.png"><img loading="lazy" decoding="async" class="size-full wp-image-3885" src="https://zappysys.com/blog/wp-content/uploads/2018/06/odbc-call-soap-api-13.png" alt="Generate Example Code for ZappySys Driver" width="572" height="618" /></a>
<div style="display: block;">Generate Example Code for ZappySys Driver</div></div>
<h2>OPENQUERY vs EXEC AT (Handling Larger SQL Text)</h2>
<p>So far we have seen examples of using OPENQUERY. It allows us to send pass-through query at remote server. The biggest limitation of OPENQUERY is it doesnt allow you to use variables inside SQL so often we have to use unpleasant looking dynamic SQL (Lots of tick, tick &#8230;.  and escape  hell). Well there is good news. With SQL 2005 and later you can use <pre class="crayon-plain-tag">EXEC( your_sql ) AT your_linked_server syntax</pre> .</p>
<p>Disadvantage of EXEC AT is you cannot do SELECT INTO like OPENQUERY. Also you cannot perform JOIN like below in EXEC AT</p><pre class="crayon-plain-tag">SELECT a.* FROM OPENQUERY(ls_json,'select * from $') a 
JOIN  OPENQUERY(ls_json,'select * from $') b ON a.id=b.id</pre><p>
However you can always do INSERT INTO MyTable EXEC(&#8230;) AT LINKEDSRV. So table must exists when you do that way.</p>
<p>Here is how to use it. To use EXEC AT you must turn on <strong>RPC OUT</strong> option. Notice how we used variable in SQL to make it dynamic. This is much cleaner than previous approach we saw.</p><pre class="crayon-plain-tag">USE [master]
GO

EXEC master.dbo.sp_addlinkedserver @server = N'ls_Json', @srvproduct=N'', @provider=N'SQLNCLI', @datasrc=N'localhost,5000', @provstr=N'Network Library=DBMSSOCN;', @catalog=N'JsonApi'
EXEC master.dbo.sp_addlinkedsrvlogin @rmtsrvname=N'ls_Json',@useself=N'False',@locallogin=NULL,@rmtuser=N'tdsuser',@rmtpassword='########'
GO

EXEC sp_serveroption 'ls_Json', 'rpc out', true;  
go

declare @tbl varchar(100)='$'
EXEC('select * from ' + @tbl ) AT ls_Json</pre><p>
Here is the difference between OPENQUERY vs EXEC approaches.</p>
<div id="attachment_7968" style="width: 721px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/openquery-vs-exec-sql-server-linked-server-text-limit.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7968" class="size-full wp-image-7968" src="https://zappysys.com/blog/wp-content/uploads/2018/03/openquery-vs-exec-sql-server-linked-server-text-limit.png" alt="SQL Server OPENQUERY vs EXEC for Linked Server - Handling Larger SQL Text (More than 8000 chars)" width="711" height="485" srcset="https://zappysys.com/blog/wp-content/uploads/2018/03/openquery-vs-exec-sql-server-linked-server-text-limit.png 711w, https://zappysys.com/blog/wp-content/uploads/2018/03/openquery-vs-exec-sql-server-linked-server-text-limit-300x205.png 300w" sizes="(max-width: 711px) 100vw, 711px" /></a><p id="caption-attachment-7968" class="wp-caption-text">SQL Server OPENQUERY vs EXEC for Linked Server &#8211; Handling Larger SQL Text (More than 8000 chars)</p></div>
<p>&nbsp;</p>
<p>If you decide to use EXEC instead of OPENQUERY then make sure below setting is ON else you will get an error.</p>
<p>Under the Linked Server Options, Enable <b>RPC</b> and <b>RPC Out</b> and Disable Promotion of Distributed Transactions<b>(MSDTC)</b>.</p>
<div id="attachment_10949" style="width: 700px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/linked-server-options-rpc-msdtc.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-10949" class="size-full wp-image-10949" src="https://zappysys.com/blog/wp-content/uploads/2018/03/linked-server-options-rpc-msdtc.png" alt="linked-server-options-rpc-msdtc" width="690" height="625" srcset="https://zappysys.com/blog/wp-content/uploads/2018/03/linked-server-options-rpc-msdtc.png 690w, https://zappysys.com/blog/wp-content/uploads/2018/03/linked-server-options-rpc-msdtc-300x272.png 300w" sizes="(max-width: 690px) 100vw, 690px" /></a><p id="caption-attachment-10949" class="wp-caption-text">RPC OUT setting for EXEC AT statement in SQL Server Linked Server</p></div>
<p>&nbsp;</p>
<h2>Configure Firewall Settings</h2>
<p>So far we have assumed that Gateway is running on the same machine as SQL Server. However there will be a case when ZappySys ODBC PowerPack is installed on a different machine than SQL Server.  In such case you may have to perform additional Firewall configurations. On most computers firewall settings wont allow outside traffic to ZappySys Data Gateway. In such case perform following steps to allow other machines to connect to Gateway.</p>
<ol>
<li>Search for Windows Firewall Advanced Security in start menu.</li>
<li>Under Inbound Rules &gt; Right click and click [New Rule] &gt;&gt; Click Next</li>
<li>Select Port on Rule Type &gt;&gt; Click Next</li>
<li>Click on TCP and enter port number under specified local port as 5000 (use different one if you changed Default port) &gt;&gt; Click Next</li>
<li>Select Profile (i.e. Private, Public) &gt;&gt; Click Next</li>
<li>Enter Rule name [i.e. ZappySys Data Gateway &#8211; Allow Inbound ] &gt;&gt; Click Next</li>
<li>Click OK to save the rule</li>
</ol>
<div id="attachment_7250" style="width: 826px" class="wp-caption alignnone"><a href="https://zappysys.com/blog/wp-content/uploads/2018/03/zappysys-data-gateway-firewall-rule-allow-traffic.png"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-7250" class="size-full wp-image-7250" src="https://zappysys.com/blog/wp-content/uploads/2018/03/zappysys-data-gateway-firewall-rule-allow-traffic.png" alt="ZappySys Datagateway - Allow Inbound Traffic on Port 5000 Firewall Rule" width="816" height="319" srcset="https://zappysys.com/blog/wp-content/uploads/2018/03/zappysys-data-gateway-firewall-rule-allow-traffic.png 816w, https://zappysys.com/blog/wp-content/uploads/2018/03/zappysys-data-gateway-firewall-rule-allow-traffic-300x117.png 300w, https://zappysys.com/blog/wp-content/uploads/2018/03/zappysys-data-gateway-firewall-rule-allow-traffic-768x300.png 768w" sizes="(max-width: 816px) 100vw, 816px" /></a><p id="caption-attachment-7250" class="wp-caption-text">ZappySys Datagateway &#8211; Allow Inbound Traffic on Port 5000 Firewall Rule</p></div>
<h2>Known Issues</h2>
<p>In this section we will discuss some known issues when using OPENQUERY / Data Gateway Connectivity</p>
<h3>Error: The data is invalid</h3>
<p>There will be a time when you start facing odd errors such as below. Possible</p><pre class="crayon-plain-tag">OLE DB provider "SQLNCLI11/MSOLEDBSQL" for linked server "Zs_Csv" returned message "Deferred prepare could not be completed.".
OLE DB provider "SQLNCLI11/MSOLEDBSQL" for linked server "Zs_Csv" returned message "Communication link failure".
Msg 13, Level 16, State 1, Line 0

Session Provider: The data is invalid.</pre><p>
<strong>Possible Cause:</strong></p>
<p>There are few reasons for such error but below are two main reasons</p>
<ul>
<li>If query length is more than 2000 Characters long such as below then you might get such error<br />
<pre class="crayon-plain-tag">SELECT * FROM OPENQUERY(LS, '--some really long text more than 2000 chars--')</pre>
</li>
<li>If query contains multiple OPENQUERY statements for JOIN / UNION like below then also it might fail (Gateway doesnt support parallel queries on a single connection &#8211; MARS compatibility issue).<br />
<pre class="crayon-plain-tag">select a.id, b.name from OPENQUERY(LS, 'select * from tbl1') a join OPENQUERY(LS, 'select * from tbl2') b on a.id=b.id</pre>
</li>
</ul>
<p><strong>Possible Fix:</strong></p>
<p>There are few ways to fix above error based on reason why you getting this error (i.e. Query Length issue OR JOIN/UNION in the same statement)</p>
<ul>
<li>If your query has long SQL (more than 2000 chars ) then reduce SQL length using different techniques
<ul>
<li>e.g. use SELECT * FROM MyTable rather than SELECT col1,col2&#8230; FROM MyTable</li>
<li>Use Meta Option in WITH clause if you must use column name. (e.g. SELECT * FROM MyTable WITH(META=&#8217;c:\meta.txt&#8217;) this way you can define column in Meta file rather than SELECT query. <a href="https://zappysys.com/blog/caching-metadata-odbc-drivers-performance/" target="_blank" rel="noopener">Check this article</a></li>
<li>Consider using EXECT (&#8230;.) AT [Linked_Server_name] option rather than OPENQUERY so you can use very long SQL (See next section on EXEC..AT usecase)</li>
<li>Consider <a href="https://zappysys.com/blog/odbc-drivers-custom-objects-feature/" target="_blank" rel="noopener">using Virtual Table / Stored Proc</a> to wrap long SQL so your call is very small (where usp_GetOrdersByYear is custom proc created on ZappySys Driver UI)<br />
<pre class="crayon-plain-tag">SELECT * FROM OPENQUERY(LS, 'EXEC usp_GetOrdersByYear 2021')</pre>
</li>
</ul>
</li>
<li>If your query uses JOIN  / UNION with multiple OPENQUERY in same SQL then use multiple Linked servers (one for each OPENQUERY clause) as below.<br />
<pre class="crayon-plain-tag">select a.id, b.name from OPENQUERY(LS_1, 'select * from tbl1') a join OPENQUERY(LS_2, 'select * from tbl2') b on a.id=b.id</pre>
</li>
</ul>
<h3>Error: Unable to begin a distributed transaction (When INSERT + EXEC used)</h3>
<p>If you try to use EXEC statement and try to insert data into table (like below) you might get below error unless MSDTC option is turned off.</p><pre class="crayon-plain-tag">INSERT INTO MyTable EXEC('select * from tbl') AT MyLinkedServer</pre><p>
</p><pre class="crayon-plain-tag">"Protocol error in TDS stream"
The operation could not be performed because OLE DB provider "SQLNCLI11" for linked server "ls_Json2" was unable to begin a distributed transaction.
--OR--
The operation could not be performed because OLE DB provider "MSOLEDBSQL" for linked server "ls_Json" was unable to begin a distributed transaction.</pre><p>
<b>Solution:</b><br />
<strong>Method-1:</strong> Go to linked server properties | Server Options | <strong>Enable Promotion of Distributed Transaction</strong> | Change to false (Default is true)<br />
Now your try your INSERT with EXEC AT and it should work</p>
<p><strong>Method-2: </strong>Run the below command if you dont want to use UI</p><pre class="crayon-plain-tag">EXEC master.dbo.sp_serveroption @server=N'My_Linked_Server', @optname=N'remote proc transaction promotion', @optvalue=N'false'</pre><p>
<h3>Error: Cannot use OPENQUERY with JOIN / UNION</h3>
<p>When you perform JOIN  / UNION ALL on the same Linked Server it may fail to process sometimes because Datagateway doesnt support parallel query requests on the same connection. Workaround for that would be create multiple linked servers for the same datasource. See above section for the same workaround.</p>
<h3>Error: Truncation errors due to data length mismatch</h3>
<p>Many time you may receive truncation errors if Table column is length is less than actual column size from query column. To solve this issue use New version of Data gateway ( check &#8211; Use nvarchar(max) for string options &#8211; Found on General Tab)</p>
<h2>Performance Tips</h2>
<p>Now lets look at few performance tips</p>
<h3>Use INSERT INTO rather than SELECT INTO to avoid extra META request</h3>
<p>We discussed some Pros and Cons of <strong>OPENQUERY</strong> vs <strong>EXEC (&#8230;) AT</strong> in previous section. One obvious advantage of EXEC (&#8230;.) AT is it reduces number of requests to driver (It sends pass through query). With EXEC you cannot load data dynamically like SELECT INTO tmp FROM OPENQUERY. Table must exist before hand if you use EXEC.</p><pre class="crayon-plain-tag">INSERT INTO tmp_API_Report_Load(col1,col2)
EXEC('select col1,col2 from some_api_table') AT [API-LINKED-SERVER]
--OR--
INSERT INTO tmp_API_Report_Load(col1,col2)
select col1,col2 from OPENQUERY([API-LINKED-SERVER], 'select col1,col2 from some_api_table')</pre><p>
Advantage of this method is your Query speed will increase because system calls API only once when you call EXEC AT. In OPENROWSET it needs to call above query twice (Once to obtain metadata and once to get data).</p>
<h3>Use Cached Metadata if possible</h3>
<p>By default, most of the SQL sent to Data gateway need to invoke two phases. First, get metadata and second fetch data. You can bypass meta API call by supplying static metadata. Use META property in WITH clause as per <a href="https://zappysys.com/blog/caching-metadata-odbc-drivers-performance/" target="_blank" rel="noopener">this article</a> to speed up your SQL.</p>
<p>&nbsp;</p>
<h2>Conclusion</h2>
<p>To conclude, we can say that using ZappySys JSON / XML Drivers we can query JSON / XML Files and call REST API or SOAP Web Service using familiar SQL Language. All you need to do is install ZappySys ODBC Drivers, configure it in the ODBC DSN and use ZappySys Gateway as a Proxy. Finally, you add a Linked Server in SQL Server to connect to ZappySys Data Gateway. Feel free to download  <a href="https://zappysys.com/products/odbc-powerpack/">ZappySys Drivers here</a>. You can contact ZappySys Team <a href="https://zappysys.com/support/" target="_blank" rel="noopener">here</a> if you need any API integration help.</p>
<h2>References</h2>
<ul>
<li><a href="https://zappysys.com/onlinehelp/odbc-powerpack/">ZappySys ODBC PowerPack online help</a></li>
<li><a href="https://docs.microsoft.com/en-us/sql/relational-databases/json/json-data-sql-server">JSON data in SQL Server</a></li>
<li><a href="https://docs.microsoft.com/en-us/sql/relational-databases/linked-servers/linked-servers-database-engine">Linked Servers (Database Engine)</a></li>
</ul>
<p>Keywords: Call REST API, SQL SERVER, JSON</p>
<p>The post <a href="https://zappysys.com/blog/import-rest-api-json-sql-server/">How to import REST API in SQL Server (Call JSON / XML SOAP Service)</a> appeared first on <a href="https://zappysys.com/blog">ZappySys Blog</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
