在存储过程中使用含Always Encrypted列的SQL遇执行错误
问题原因
错误的核心是隐式类型转换不兼容:单独执行SQL语句时,客户端驱动会自动适配加密列的Unicode类型(nvarchar),但存储过程的编译逻辑无法处理varchar到加密nvarchar(15)的隐式转换,导致类型冲突。
解决方案
1. 严格匹配列与参数的类型
确保存储过程中涉及加密列的所有操作,类型与源/目标列完全一致(nvarchar(15),而非varchar)。
无参数存储过程示例
CREATE OR ALTER PROCEDURE uspMoveToTarget AS BEGIN SET NOCOUNT ON; -- 直接选择源列插入,确保类型完全匹配 INSERT INTO dbo.TargetTable (CustomerAlternateKey) SELECT CustomerAlternateKey FROM dbo.DimCustomer; END GO
带参数存储过程示例
如果存储过程需要接收参数,必须定义为nvarchar(15),传入参数时要加Unicode前缀N:
CREATE OR ALTER PROCEDURE uspMoveToTarget @CustomerAlternateKey nvarchar(15) AS BEGIN SET NOCOUNT ON; INSERT INTO dbo.TargetTable (CustomerAlternateKey) VALUES (@CustomerAlternateKey); END GO -- 执行示例 EXEC uspMoveToTarget @CustomerAlternateKey = N'AW00000001';
2. 在启用列加密的会话中创建存储过程
存储过程的元数据需要正确识别加密列的属性,必须在开启column encryption setting=Enabled的SSMS连接中创建/修改存储过程:
- 断开当前SSMS连接
- 重新连接时,在「连接属性」→「附加连接参数」中添加
column encryption setting=Enabled - 重新执行存储过程的创建语句
3. 避免触发隐式转换的操作
- 不要对加密列使用会转换为
varchar的函数(如未指定类型的CONVERT) - 确保源表
dbo.DimCustomer.CustomerAlternateKey与目标表dbo.TargetTable.CustomerAlternateKey的定义完全一致:都是nvarchar(15),使用同一列加密密钥(CEK)和确定性加密
验证执行
完成上述步骤后,执行存储过程即可正常运行:
EXEC uspMoveToTarget;
内容的提问来源于stack exchange,提问作者lem
相关产品推荐
相关产品推荐

