如何将 BACPAC 文件导入 Azure SQL 并覆盖现有数据库?

Ran*_*der 6 sql-server azure-sql-database

假设我有一个名为 MyDatabase 的本地数据库。我想将它移动到 Azure SQL 并替换当前驻留在那里的名为 MyDatabase 的现有数据库。我知道如何在本地创建 BACPAC 文件。我知道如何将 BACPAC 导入到我的 Azure 存储帐户。但是,一旦 BACPAC 位于 Azure 存储中,我不知道使用存储中的副本覆盖现有 MyDatabase 数据库的首选方法。我可以导入 BACPAC 文件并创建第二个数据库,然后删除第一个,并重命名刚刚导入的数据库。但是,这样做是最好的还是首选的方式?

Sql*_*ide 12

你是对的。在 Azure 中,您无法在现有数据库上进行还原。

  • 您必须使用不同的名称进行恢复。
  • 删除旧数据库
  • 将新的数据库重命名为旧的数据库名称。

您有几种方法可以从 .BACPAC 文件中恢复。

  1. 您可以使用.\sqlpackage.exe命令行工具直接从您的本地 .BACPAC 位置 执行此操作。

    .\sqlpackage.exe /a:Import /sf:C:\filename.bacpac /tsn:ServerName.database.windows.net /tdn:destinationDBName ` /tu:adminaccountName@serverName /tp:$credentialPW

  2. 您还可以使用在存储帐户中上传的副本。

    $ResourceGroupName = "RGName" $ServerName = 'ServerName' $DatabaseName = "DestinationDBName"

    $StorageName = "StorageAccountName" $StorageKeyType = "StorageAccessKey" $StorageUri = "http://$StorageName.blob.core.windows.net/swwstoragecontainer/BackpacFileName.bacpac" $StorageKey = "********* ******************************”

    $credential = 获取凭据

    $importRequest = New-AzureRmSqlDatabaseImport -ResourceGroupName $ResourceGroupName -ServerName $ServerName -DatabaseName $DatabaseName -StorageKeytype $StorageKeyType -StorageKey $StorageKey -StorageUri $StorageUri -AdministratorLogin $credential.UserName -AdministratorLoginPassword $credential.Password ` -Edition Standard -ServiceObjectiveName S0 -DatabaseMaxSizeBytes 50000

    Get-AzureRmSqlDatabaseImportExportStatus -OperationStatusLink $importRequest.OperationStatusLink

  3. 在门户中,您可以将.BACPAC文件作为数据库直接导入服务器。

  • 看来我也可以使用 SSMS 将我的本地副本部署到 Azure SQL,方法是右键单击 SSMS 中的数据库,选择“任务”,然后选择“将数据库部署到 Microsoft SQL Azure”。你这样做了吗? (3认同)
  • 你是对的,是的,我做到了。这是我在演示文稿中展示的最简单的方法之一。详细信息 [此处](http://sqlworldwide.com/how-to-migrate-a-sql-database-to-microsoft-azure-sql-v12/)。 (2认同)

Tum*_*nin 8

在 Azure 中,您无法在现有数据库上进行还原。(C)

显然,不是真的。您可以将 .bacpac 文件还原到现有的 Azure SQL 数据库中,例如,在您确实需要保留相同的 Azure SQL 数据库实例的情况下,因为它已合并到 Azure 环境中。一个必要条件是:目标数据库必须是空的,即就像刚刚创建为新的一样。但是如果你已经有一个目标数据库,它不是空的(当然!),你可以“清理”数据库,在其上下文中运行以下脚本,以超级用户身份登录:

DECLARE @sql NVARCHAR(2000)

WHILE EXISTS(SELECT TOP(1) * FROM SYS.TRIGGERS WHERE is_ms_shipped = 0)
BEGIN
    SELECT TOP(1) @sql = 'DROP TRIGGER IF EXISTS [' + [name] + '] ON ' + parent_class_desc COLLATE database_default --SQL_Latin1_General_CP1_CI_AS
    FROM SYS.TRIGGERS
    WHERE is_ms_shipped = 0
    PRINT @sql
    EXEC (@sql)
END

WHILE EXISTS(SELECT TOP(1) * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'PROCEDURE')
BEGIN
    SELECT TOP(1) @sql = 'DROP PROCEDURE IF EXISTS [' + ROUTINE_SCHEMA + '].[' + ROUTINE_NAME + ']'
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = 'PROCEDURE'
    PRINT @sql
    EXEC (@sql)
END

WHILE EXISTS(SELECT TOP(1) * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'FUNCTION')
BEGIN
    SELECT TOP(1) @sql = 'DROP FUNCTION IF EXISTS [' + ROUTINE_SCHEMA + '].[' + ROUTINE_NAME + ']'
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_TYPE = 'FUNCTION'
    PRINT @sql
    EXEC (@sql)
END

WHILE EXISTS(SELECT TOP(1) * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY')
BEGIN
    SELECT TOP(1) @sql = 'ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']'
    FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
    WHERE CONSTRAINT_TYPE='FOREIGN KEY'
    PRINT @sql
    EXEC (@sql)
END

WHILE EXISTS(SELECT TOP(1) * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'VIEW' AND TABLE_SCHEMA != 'sys')
BEGIN
    SELECT TOP(1) @sql = 'DROP VIEW [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = 'VIEW' AND TABLE_SCHEMA != 'sys'
    PRINT @sql
    EXEC (@sql)
END

WHILE EXISTS(SELECT TOP(1) * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME != '__MigrationHistory')
BEGIN
    SELECT TOP(1) @sql = 'DROP TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME != '__MigrationHistory'
    PRINT @sql
    EXEC (@sql)
END

--SELECT * FROM SYS.TYPES WHERE is_user_defined = 1
--SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME != '__MigrationHistory'
--SELECT * FROM SYS.TRIGGERS WHERE is_ms_shipped = 0
--DROP TRIGGER IF EXISTS [backup_objects] ON DATABASE
Run Code Online (Sandbox Code Playgroud)

最后 4 条语句是可选的。其中前 3 个用于检查/查看某些参数,最后一个用于删除特定的数据库级触发器(如果存在)。

之后,您可以使用标准的 sqlpackage.exe 实用程序将您拥有的 .bacpac 文件还原到目标数据库,并在管理提升的命令行窗口中运行它,如下所示:

“C:\Program Files (x86)\Microsoft SQL Server\140\DAC\bin\sqlpackage.exe” /a:Import /sf:"C:\Users\[username1]\Documents\SQL Server Management Studio\DAC Packages\[SourceDBName.bacpac]" /tsn:[azureSQLServerName].database.windows.net /tdn:[TargetAzureSQLDBName] /tu:[DBAdminLogin] /tp:[DBAdminPassword]
Run Code Online (Sandbox Code Playgroud)

只需将 [braced_values] 替换为真实值,它应该可以工作。运行时,该实用程序可能会显示一条警告消息,以黄色显示,如下所示:

初始化部署 对象 [data_0] 存在于目标中,但即使您选中了“为目标数据库中但不在源中的对象生成删除语句”复选框,它也不会被删除。对象 [log] 存在于目标中,但即使您选中了“为目标数据库中但不在源中的对象生成删除语句”复选框,它也不会被删除。

你可以无视它。根据数据库的大小和复杂性,恢复过程可能需要很长时间,因此请务必等到它完成,并显示消息:成功导入数据库。

希望有帮助。