我有一个“始终加密”设置为打开的SQL Server 2016数据库。我们有多个加密列和一个处理更新的存储过程。
CREATE PROCEDURE UpdateRecord
@ID INT,
@EncryptedParameter01 NVARCHAR(255) = NULL,
@EncryptedParameter02 NVARCHAR(255) = NULL,
@EncryptedParameter03 NVARCHAR(255) = NULL,
@EncryptedParameter04 NVARCHAR(255) = NULL,
@EncryptedParameter05 NVARCHAR(255) = NULL,
@EncryptedParameter06 NVARCHAR(255) = NULL,
@EncryptedParameter07 NVARCHAR(255) = NULL,
@EncryptedParameter08 NVARCHAR(255) = NULL,
@EncryptedParameter09 NVARCHAR(255) = NULL,
@EncryptedParameter10 NVARCHAR(255) = NULL,
@EncryptedParameter11 NVARCHAR(255) = NULL,
@EncryptedParameter12 NVARCHAR(255) = NULL,
@EncryptedParameter13 NVARCHAR(255) = NULL,
@EncryptedParameter14 NVARCHAR(255) = NULL,
@EncryptedParameter15 NVARCHAR(255) = NULL,
@EncryptedParameter16 NVARCHAR(255) = NULL,
@EncryptedParameter17 NVARCHAR(255) = NULL,
@EncryptedParameter18 NVARCHAR(255) = NULL,
@EncryptedParameter19 NVARCHAR(255) = NULL,
@EncryptedParameter20 NVARCHAR(255) = NULL
AS
BEGIN
UPDATE myTable
SET Field01 = CASE WHEN @EncryptedParameter01 IS NULL THEN Field01 ELSE @EncryptedParameter01 END,
Field02 = CASE WHEN @EncryptedParameter02 IS NULL THEN Field02 ELSE @EncryptedParameter02 END,
Field03 = CASE WHEN @EncryptedParameter03 IS NULL THEN Field03 ELSE @EncryptedParameter03 END,
Field04 = CASE WHEN @EncryptedParameter04 IS NULL THEN Field04 ELSE @EncryptedParameter04 END,
Field05 = CASE WHEN @EncryptedParameter05 IS NULL THEN Field05 ELSE @EncryptedParameter05 END,
Field06 = CASE WHEN @EncryptedParameter06 IS NULL THEN Field06 ELSE @EncryptedParameter06 END,
Field07 = CASE WHEN @EncryptedParameter07 IS NULL THEN Field07 ELSE @EncryptedParameter07 END,
Field08 = CASE WHEN @EncryptedParameter08 IS NULL THEN Field08 ELSE @EncryptedParameter08 END
, Field09 = CASE WHEN @EncryptedParameter09 IS NULL THEN Field09 ELSE @EncryptedParameter09 END
, Field10 = CASE WHEN @EncryptedParameter10 IS NULL THEN Field10 ELSE @EncryptedParameter10 END
, Field11 = CASE WHEN @EncryptedParameter11 IS NULL THEN Field11 ELSE @EncryptedParameter11 END
, Field12 = CASE WHEN @EncryptedParameter12 IS NULL THEN Field12 ELSE @EncryptedParameter12 END
, Field13 = CASE WHEN @EncryptedParameter13 IS NULL THEN Field13 ELSE @EncryptedParameter13 END
, Field14 = CASE WHEN @EncryptedParameter14 IS NULL THEN Field14 ELSE @EncryptedParameter14 END
, Field15 = CASE WHEN @EncryptedParameter15 IS NULL THEN Field15 ELSE @EncryptedParameter15 END
, Field16 = CASE WHEN @EncryptedParameter16 IS NULL THEN Field16 ELSE @EncryptedParameter16 END
, Field17 = CASE WHEN @EncryptedParameter17 IS NULL THEN Field17 ELSE @EncryptedParameter17 END
, Field18 = CASE WHEN @EncryptedParameter18 IS NULL THEN Field18 ELSE @EncryptedParameter18 END
, Field19 = CASE WHEN @EncryptedParameter19 IS NULL THEN Field19 ELSE @EncryptedParameter19 END
, Field20 = CASE WHEN @EncryptedParameter20 IS NULL THEN Field20 ELSE @EncryptedParameter20 END
WHERE ID = @ID
END
我们实际的存储过程更加复杂,这只是给您一个想法。如果仅使用少数几个参数调用它,则效果很好。但是,如果调用次数超过10,则该过程将失败。
错误消息是
消息206,级别16,状态2,过程UpdateRecord,行0 [批处理开始行0]
操作数类型冲突:nvarchar与通过(encryption_type ='DETERMINISTIC',encryption_algorithm_name ='AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name ='MyNamedKey',column_encryption_key_database_name ='MyData_'加密的nvarchar(255)不兼容
这不仅取决于单个参数是否失败,还取决于传递的字符数。另外,在添加加密之前,此过程运行良好。
关于为什么会发生这种情况的更多信息,我们将不胜感激。
非常感谢。
已修改为包含通话:
我通过VB和T-SQL都看到了这一点。最简单的情况是来自SSMS的直接呼叫。我确实选中了“为始终加密启用参数化”。如果发送了10个或更少的参数,则可以正确传递参数并正常运行。示例调用:
DECLARE @PassedEncryptedParameter01 NVARCHAR(255) = 'Updated value 01'
EXEC UpdateRecord @Id=12345, @EncryptedParameter01 = @PassedEncryptedParameter01
如您所见,我已经声明了类型,因此可以匹配。这里的问题不是参数的定义方式,而是发送的参数数量。