Zen*_*cki 7 sql import azure bacpac
将db from azure bacpac文件导入本地sql server 2016时,我发现以下错误.
Error SQL72014: .Net SqlClient Data Provider: Msg 102, Level 15, State 1, Line 1 Incorrect syntax near 'EXTERNAL'.
Error SQL72045: Script execution error. The executed script: CREATE EXTERNAL DATA SOURCE [BoxDataSrc]
WITH (
TYPE = RDBMS,
LOCATION = N'MYAZUREServer.database.windows.net',
DATABASE_NAME = N'MyAzureDb',
CREDENTIAL = [SQL_Credential]
);
Run Code Online (Sandbox Code Playgroud)
(Microsoft.SqlServer.Dac)
SQL*_*oug 10
我今天也遇到了同样的问题。由于“ WITH(TYPE = RDBMS)”仅适用于Azure SQL DB,因此在尝试将bacpac本地导入到SQL Server 2017时会出现错误。由于这篇文章,我确实找到了解决方案:
https://blogs.msdn.microsoft.com/azuresqldbsupport/2017/08/16/editing-a-bacpac-file/
相关步骤重写如下:
查找model.xml文件并对其进行编辑,以删除如下所示的部分:
<Element Type="SqlExternalDataSource" Name="[BoxDataSrc]">
<Property Name="DataSourceType" Value="1" />
<Property Name="Location" Value="MYAZUREServer.database.windows.net" />
<Property Name="DatabaseName" Value="MyAzureDb" />
<Relationship Name="Credential">
<Entry>
<References Name="[SQL_Credential]" />
</Entry>
</Relationship>
</Element>
Run Code Online (Sandbox Code Playgroud)如果您有多个这种类型的外部数据源,则可能需要为每个数据源重复步骤3。我只有一个。
现在,您需要重新生成model.xml的校验和,以便bacpac不会认为它已被篡改(因为您刚刚对其进行了篡改)。创建一个名为computeHash.ps1的PowerShell文件,并将此代码放入其中。
$modelXmlPath = Read-Host "model.xml file path"
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create("System.Security.Cryptography.SHA256CryptoServiceProvider")
$fileStream = new-object System.IO.FileStream ` -ArgumentList @($modelXmlPath, [System.IO.FileMode]::Open)
$hash = $hasher.ComputeHash($fileStream)
$hashString = ""
Foreach ($b in $hash) { $hashString += $b.ToString("X2") }
$fileStream.Close()
$hashString
Run Code Online (Sandbox Code Playgroud)运行PowerShell脚本,并为其提供已解压缩和编辑的model.xml文件的文件路径。它将返回一个校验和值。
复制校验和值,然后打开Origin.xml并替换现有校验和,朝着如下所示的行的底部:
<Checksum Uri="/model.xml">9EA0F06B282D4F42955C78A98822A31AA0ED0225CB131B8759379055A482D01F</Checksum>
Run Code Online (Sandbox Code Playgroud)保存并关闭Origin.xml,然后选择所有文件并将其放入新的zip文件中,并将扩展名重命名为bacpac。
现在,您可以使用这个新的bacpac导入数据库,而不会出现错误。它对我有用,它也可以对你有用。
根据@SQLDoug 的回答,如果您的 Azure SQL 数据库具有外部表(即来自其他数据库的链接表),就会发生这种情况。您可以在此处的 SSMS 中检查:
已接受答案的附录
如果您删除这些外部表的数据源,您还需要删除 model.xml 文件中使用这些数据源的 SqlExternalTable 元素,它们将如下所示:
<Element Type="SqlExternalTable" Name="[dbo].[DeliveryMethodsRestored]">
<Property Name="ExternalSchemaName" Value="dbo" />
<Property Name="ExternalObjectName" Value="DeliveryMethods" />
<Property Name="IsAnsiNullsOn" Value="True" />
<Property Name="IsQuotedIdentifierOn" Value="False" />
<Relationship Name="Columns">
<Entry>
<Element Type="SqlSimpleColumn" Name="[dbo].[DeliveryMethodsRestored].[DeliveryMethodId]">
<Property Name="IsNullable" Value="False" />
<Relationship Name="TypeSpecifier">
<Entry>
SNIP....
</Element>
Run Code Online (Sandbox Code Playgroud)
如果您在model.xml 中搜索'SqlExternalTable',您会很容易找到它们。
解决此问题的替代方法
不是在下载后更正 bacpac,另一种处理此问题的方法是在创建 bacpac 之前删除外部表,即:
这种方法的优点是您不会从实时数据库创建 bacpac,这显然“可能导致导出的表数据不一致,因为与 SQL Server 的物理备份/恢复不同,导出不保证事务一致性”。
如果这是您可能经常做的事情,您可能会编写脚本来自动执行上述大部分步骤。