跨服务器还原bacpac文件后如何保持user_type_id值一致?
解决自定义用户类型user_type_id跨服务器一致的办法
核心说明
SQL Server的user_type_id是系统自动生成的标识值,bacpac备份/还原流程不会保留这个ID,要实现跨服务器一致,只能通过手动预创建类型并指定ID的方式干预。
步骤1:导出原服务器自定义类型的信息
在原服务器执行以下查询,获取所有用户自定义类型的定义和对应的user_type_id:
SELECT t.name AS type_name, t.user_type_id, t.system_type_id, t.max_length, t.precision, t.scale, t.collation_name, c.definition AS type_definition FROM sys.types t LEFT JOIN sys.sql_modules c ON t.type_object_id = c.object_id WHERE t.is_user_defined = 1;
步骤2:在目标服务器预创建类型并指定ID
必须在还原bacpac之前执行此步骤,避免还原时类型冲突:
- 对于基础自定义类型(比如示例中的Email),直接用
CREATE TYPE指定原ID:
执行前先查询CREATE TYPE [dbo].[Email] FROM varchar(256) COLLATE SQL_Latin1_General_CP1_CI_AS WITH USER_TYPE_ID = 257;sys.types确认目标服务器的该ID未被占用。 - 对于CLR自定义类型或结构化类型,先创建依赖的程序集(CLR类型需要),再指定ID创建类型:
-- 示例CLR类型创建 CREATE ASSEMBLY [MyCLRTypes] FROM 'C:\Path\To\MyCLRTypes.dll' WITH PERMISSION_SET = SAFE; CREATE TYPE [dbo].[MyCLRType] EXTERNAL NAME [MyCLRTypes].[MyNamespace.MyCLRType] WITH USER_TYPE_ID = 258;
步骤3:调整bacpac还原规则
预创建类型后,还原时要跳过bacpac中自带的类型创建步骤:
- 使用SqlPackage.exe还原时,添加参数跳过用户自定义类型:
SqlPackage.exe /Action:Import /SourceFile:"C:\Backup\MyDB.bacpac" /TargetConnectionString:"Server=TargetServer;Database=MyDB;Trusted_Connection=True;" /p:IgnoreUserDefinedTypes=True - 使用SSMS还原时,在「高级」选项中勾选「忽略用户定义类型」。
注意事项
- 预创建的类型必须和原服务器定义完全一致(数据类型、长度、排序规则、CLR程序集版本等),否则会引发兼容性问题。
user_type_id取值范围为256-16383,避开系统预留ID。- 若目标服务器已有其他自定义类型,务必确认指定ID未被占用,否则会创建失败。
内容的提问来源于stack exchange,提问作者tdinpsp
相关产品推荐
相关产品推荐

