Os bancos de dados armazenados no Azure podem ser exportados para uma estrutura de arquivo conhecida como Data-tier Application File (BACPAC). Os bacpac funcionam como uma estrutura de backup lógico semelhante a outros SGBDs. Eles podem ser utilizados como backup e também como ferramenta para migração de instância incluindo on-primises e cloud.
Uma vez exportado o bacpac pode ser importado na instância de destino por meio do SQL Server Management Studio (SSMS). Para isto, no Object Explorer basta clicar com o botão direito em Databases e então selecionar Import Data-tier Applicaiton para iniciar o assistente de importação.
O processo de importação é bem simples. Primeiro devemos escolher qual a origem que iremos realizar a importação dos dados: a partir de um arquivo local ou diretamente do Azure (Microsoft Azure Container). Em seguida, em instâncias on-premises, nós devemos escolher o nome do novo banco de dados assim como o diretório em que serão armazenados os seus dados e o arquivo de log. Ao avançarmos para a próxima etapa é exibida a tela de validação que mostra se existem impedimentos para realizar a ação. Por fim, temos a tela que resume a operação com informações de origem de dados e configuração do destino. Para completar a ação, devemos clicar no botão “Finish” e acompanhar o progresso do restore. Por fim, há a página de resultado indicando se a operação foi concluída com sucesso.
E se o processo de importação não der certo?
O Azure e a instância local são bancos de dados distintos e que possuem recursos e configurações diferentes. Por isso, podemos nos deparar com algumas features que ainda não estão disponíveis para a versão on-premisses. Outro problema que podemos enfrentar é o uso de collations diferentes que invalidar a operação de importação do BACPAC principalmente durante a fase de importação de procedures e de functions. Nestes cenários, devemos inicialmente identificar a causa do erro da importação para que sejam realizadas ações para contornar o problema.
O primeiro passo é olhar o log de erro da importação e mapear qual objetivo não teve êxito na importação. Em seguida devemos ajustar a estrutura do BACPAC para resolver o conflito. Para isto precisamos entender como o BACPAC está estruturado.
Arquivos BACPAC são arquivos compactados como o ZIP. Para acessar o conteúdo do arquivo, podemos trocar a extensão de bacpac para o ZIP, por exemplo “PortalDoCliente.bacpac.zip” e utilizar o Windows Explorer para abrir o arquivo zip normalmente.

Um breve resumo da estrutura de um arquivo BACPAC. No diretório _rels temos um XML que indica o caminho do arquivo BCP e a tabela na qual ele deverá ser importado. O diretório Data é composto por vários subdiretórios sendo um para cada tabela de dados. O arquivo [Content_Types.xml] define os tipos de dados armazenados no BACPAC, i.e., ele é composto por arquivos XML do tipo XML e arquivos BCP do tipo octet-stream. DacMetadata.xml armazena informações sobre o data-tier application (nome e versão). Origin.xml traz as configurações do BACPAC indicando quantos objetos e quais os tipos de objetos foram exportados além de trazer também um checksum de arquivo model.xml para garantir a consistência dos dados. Por fim, nós temos o model.xml que mantém a definição de todos os objetos e permissões necessárias para reconstrução do banco de dados do BACPAC. É neste arquivo que iremos concentrar nossos esforços para restaurar o banco de dados.
No nosso cenário estamos tentando importar um BACPAC chamado portaldocliente-dev.bacpac. Nele existe uma permissão que existe apenas no SQL do Azure: “ADMINISTER BULK OPERATIONS”. Ao tentarmos importar ocorre o seguinte erro:

Error SQL72014: .Net SqlClient Data Provider: Msg 4632, Level 16, State 1, Line 1 The permission ‘ADMINISTER DATABASE BULK OPERATIONS’ is not supported in this version of SQL Server.
Para resolver este problema precisamos realizar os seguintes passos:
- Utilizaremos uma ferramenta oficial da Microsoft chamada SqlPackage.exe. Caso tenhas o SqlPackage.exe instalado no servidor ele estará no diretório “C:\Program Files\Microsoft SQL Server\150\DAC\bin”. Para baixar a versão mais atual basta acessar o link.
- Em seguida renomearemos o arquivo bacpac para portaldocliente-dev.bacpac.zip. E extraímos uma cópia do arquivo model.xml.
- Editaremos o arquivo model.xml em um editor de texto de sua preferência. Como o arquivo model.xml tende a ficar muito grande recomendo utilizar o Notepad++ ou VSCode.
- Iremos procurar pela entrada AdministerDatabaseBulkOperations. E remover toda a tag <Element> que contém esse comando de grant e salvar o arquivo model.xml.
(...)
<Element Type="SqlUser" Name="[grafana.tambau]">
<Property Name="AuthenticationType" Value="2" />
<Property Name="Password" Value="hvhxbGng={vmLbg|ofiBqy|lmsFT7_&#$!~<evcogk$&hsqD" />
</Element>
<Element Type="SqlPermissionStatement" Name="[Grant.AdministerDatabaseBulkOperations.Database].[coletauser].[dbo]">
<Property Name="Permission" Value="1116" />
<Relationship Name="Grantee">
<Entry>
<References Name="[coletauser]" />
</Entry>
</Relationship>
<Relationship Name="SecuredObject">
<Entry>
<References Disambiguator="1" />
</Entry>
</Relationship>
</Element>
<Element Type="SqlPermissionStatement" Name="[Grant.AlterAnyExternalDataSource.Database].[coletauser].[dbo]">
<Property Name="Permission" Value="1109" />
<Relationship Name="Grantee">
<Entry>
<References Name="[coletauser]" />
</Entry>
</Relationship>
(...)
Após a alteração o código acima ficará:
(...)
<Element Type="SqlUser" Name="[grafana.tambau]">
<Property Name="AuthenticationType" Value="2" />
<Property Name="Password" Value="hvhxbGng={vmLbg|ofiBqy|lmsFT7_&#$!~<evcogk$&hsqD" />
</Element>
<Element Type="SqlPermissionStatement" Name="[Grant.AlterAnyExternalDataSource.Database].[coletauser].[dbo]">
<Property Name="Permission" Value="1109" />
<Relationship Name="Grantee">
<Entry>
<References Name="[coletauser]" />
</Entry>
</Relationship>
(...)
5. No prompt de comando devemos invocar o SqlPackage.exe para importar o arquivo BACPAC utilizando o model.xml que acabamos de editar. No exemplo de importação do portaldocliente-dev.bacpac utilizaremos a seguinte linha de comando.
.\SqlPackage.exe /Action:Import /SourceFile:"D:\temp\portaldocliente-dev.bacpac" /TargetConnectionString:"Data Source=(local)\SQL2019;Initial Catalog=portaldocliente-dev; Integrated Security=true;" /ModelFilePath:D:\temp\model.xml
Os parâmetros utilizados foram:
- /Action:import – para indicar que estamos importando registros com base no BACPAC.
- /SourceFile – o caminho do arquivo BACPAC.
- /TargetConnectionString – Conexão do banco de dados de destino.
- /ModelFilePath – Arquivo do model.xml que editamos para remover a permissão que não nos interessa.
Ao concluir o processo será exibida a mensagem de que a importação foi concluída com êxito e o tempo decorrido.
Importante lembrar que alguns ajustes podem ser adaptados para a realidade do SQL Server On-premises após a importação de dados. Como a substituição da permissão acima pela ‘ADMINISTER BULK OPERATIONS’. Ou um ajuste de COLLATION que causou problema na importação de procedures, poderá ser adaptado localmente.
Mais informações sobre o SqlPackage.exe:
- https://docs.microsoft.com/pt-br/sql/tools/sqlpackage/sqlpackage?view=sql-server-ver15