SQL:如何将所有表中的所有 varchar 列更改为 nvarchar?

问题描述

我需要将大约 40 个表(填充数据)中的所有 varchar 列转换为 nvarchar 列。它计划在仅用于此目的的专用 MS sql 服务器中发生。结果应移至 Azure sql

应该在哪里进行转换:在旧的 sql 上,还是在将其移动到 Azure sql Server 上之后?

根据 Remus Rusanu 的回答 https://stackoverflow.com/a/8157951/1346705,在此过程中会创建新的 nvarchar 列,并删除旧的 varchar 列。可以通过 DBCC CLEANTABLE 或使用 ALTER TABLE ... REBUILD 回收空间。删除varchar 列是否打包到备份表中,或者备份/恢复是否也删除删除的列?

能否使用通用 sql 脚本以某种方式自动化该过程?还是需要为每个单独的表编写脚本?

背景:我们是企业信息系统第三方。我们的产品从信息系统 sql 数据库中读取数据,并以在 IS 中实施成本高昂的方式呈现数据。企业信息系统现已迁移到新版本,将在Azure sql上运行。 IS 的数据库发生了很大的变化,其中一项变化是放弃旧的 8 位文本编码(varchar)并改用 Unicode(nvarchar)。我们的系统还用于收集手动输入的数据——使用与旧 IS 相同的编码。

迁移是通过做旧版本的备份(sqlCmd 产生 xxx.bak 文件)来完成的,在另一个好的旧 sql 服务器上恢复。然后我们运行脚本,删除所有可以从 IS 重建的表、视图和存储过程。主要原因之一是 sql 代码使用了新备份工具 sqlPackage.exe 不接受的功能生成 xxx.bacpac 文件。然后在 Azure sql 中还原 bacpac 文件

解决方法

应该在哪里进行转换:在旧的 SQL 上,还是在将其移动到 Azure SQL Server 上之后?

我会首先在本地 SQLServer 上执行此操作,在 Azure 数据库上运行此操作可能会导致您遇到一些问题,例如达到 DTU 限制、磁盘 IO 节流..

删除的 varchar 列是否打包到备份表中,或者备份/恢复是否也删除了删除的列?

空间不会被释放回文件系统,备份也不会处理可用空间,所以你不会在那里看到太多变化。在继续之前,你可能想阅读更多关于 dbcc cleantable 的内容..

能否使用通用 SQL 脚本以某种方式自动化该过程?还是需要为每个单独的表编写脚本?

它可以自动化,也许您可​​以使用动态sql查看列类型并进一步处理。您还必须查看这些列中是否有任何列是索引的一部分,如果是,则必须先删除它们

> ,

我建议事先对旧实例进行架构更改。即使您不费心用 DBCC CLEAANTABLEALTER...REBUILD 清理空间,产生的 bacpac 大小也将相同,因为与物理备份/恢复不同,bacpac 文件只是一种压缩包格式架构和数据。

考虑使用 SQL Server Data Tools (SSDT) 来促进架构更改。这将考虑对“通用”T-SQL 解决方案构成挑战的所有依赖项(约束、索引等)。 SSDT 通常会生成一个迁移脚本,该脚本使用临时表进行此类架构更改,因此最终结果不会浪费旧数据库中的空间。但是,您将需要数据库中有足够的未使用空间来并排包含旧/新对象。