首页 > 解决方案 > 具有始终加密列的 TSQL 上的 GETDATE() 函数错误

问题描述

我正在使用托管在 Azure 上的 SQL Server。我有一个名为“ERROR”的表,其中一个名为“DATETIME”的列启用了始终加密功能。

CREATE TABLE [dbo].[ERROR]
(
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [DATETIME] [datetime] ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
    [CODE] [varchar](10) NOT NULL,
    [MESSAGE] [varchar](500) NULL,

    CONSTRAINT [PK_ERROR] 
        PRIMARY KEY CLUSTERED ([ID] ASC)
) 

我正在运行一个存储过程以在另一个表中添加一行,但如果发现错误,则使用以下语句将错误添加到该表中:

INSERT INTO [dbo].[ERROR] ([DATETIME], [CODE], [MESSAGE])
VALUES (GETDATE(), @@ERROR, ERROR_MESSAGE())

我的问题是当我尝试GETDATE()在加密列中输入值时,出现此错误

操作数类型冲突:日期时间与使用 (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'Aeropuerto') 加密的日期时间不兼容

根据网络上的一些建议,我在 SSMS 上启用了始终加密的参数化,并首先像这样声明它DECLARE @RAISEDTIME DATETIME = '20181130'。在此之后没有引发错误并成功插入,但是当将 GETDATE() 赋值为值 [ DECLARE @RAISEDTIME DATETIME = GETDATE()] 时,我收到此错误:

列/变量“@RAISEDTIME”的加密方案不匹配。列/变量的加密方案是 (encryption_type = 'PLAINTEXT') 并且行 '3' 附近的表达式期望它是 (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = ' Aeropuerto')(或更弱)。

我尝试GETDATE()使用 ISO8601 格式化值,但出现了以下相同的错误。

你能推荐我一种用这个存储过程插入实际日期时间值的方法吗?

标签: sqlsql-servertsqlssmssql-server-2016

解决方案


您需要利用始终加密列的参数化。您必须了解,对于 AE 列,服务器没有加密密钥,因此它不可能插入在批处理脚本中声明的值。该值必须由具有加密密钥的客户端加密。

使用 SQL Server 2017,可以进行 Always Encrypted 列参数化请参阅链接文章。但它只在特定条件下有效。而且它绝对不能在 SQL Server 2016 中运行。

与大多数 Always Encrypted 列用例一样,从客户端发送值会更好。


推荐阅读