问题描述
我有一个类似于sql Server 2017中以下架构的表:
使用sql Server“始终加密”功能对Sample
列进行加密的主数据库中的表TaxID
:
CREATE TABLE [dbo].[Sample]
(
[CreatedDt] [smalldatetime] NOT NULL,[LastModDt] [smalldatetime] NOT NULL,[CompanyID] [int] IDENTITY(1,1) NOT NULL,[CompanyName] [varchar](250) NOT NULL,[CompanyTaxName] [varchar](250) NULL,[TaxID] [varchar](15) COLLATE latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY =
[CEK_Auto1],ENCRYPTION_TYPE = Deterministic,ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,[Active] [bit] NOT NULL
)
然后,出于历史记录的目的,存档数据库中还有另一个具有相同架构的表,其中TaxID
已加密。
这是Sample
数据库中的表Main_Archive
:
CREATE TABLE [dbo].[Sample]
(
[CreatedDt] [smalldatetime] NOT NULL,[CompanyArchiveID] [int] IDENTITY(1,[Active] [bit] NOT NULL
)
现在,我们希望在主Sample
表上有一个触发器,以便在每次更新时将新记录插入到存档Sample
表中。
主数据库中Sample
表的触发器如下:
CREATE TRIGGER [dbo].[tr_iud_Sample]
ON [dbo].[Sample]
FOR INSERT,UPDATE,DELETE
AS
BEGIN
SET NOCOUNT ON
DECLARE @CurrDt AS SMALLDATETIME
SELECT @CurrDt = GETDATE()
DECLARE @CurrYear AS INT
SELECT @CurrYear = YEAR(@CurrDt)
UPDATE Sample
SET LastModDt = @CurrDt,CreatedDt = CASE WHEN d.CompanyID IS NULL THEN @CurrDt ELSE Sample.CreatedDt END
FROM inserted i WITH (NOLOCK)
LEFT JOIN deleted d WITH (NOLOCK) ON d.CompanyID= i.CompanyID
WHERE Sample.CompanyID = i.CompanyID
INSERT INTO [Main_Archive].[dbo].Sample
SELECT CreatedDt,LastModDt,CompanyID,CompanyName,CompanyTaxName,TaxID,Active
FROM deleted
END
ALTER TABLE [dbo].[Sample] ENABLE TRIGGER [tr_iud_Sample]
GO
ALTER TABLE [dbo].[vendor] disABLE TRIGGER [tr_iud_Sample]
GO
但这失败了,我得到这个错误:
消息4920,级别16,状态0,第50行
操作数类型冲突:varchar(15)用(encryption_type ='DETERMINISTIC',encryption_algorithm_name ='AEAD_AES_256_CBC_HMAC_SHA_256',column_encryption_key_name ='CEK_Auto1',column_encryption_key_database_name ='NCI_COMMON'='NCI_COMMON'
有没有一种方法可以对加密表进行触发,如果可以,如何实现 所需的功能?
此外,如果sql Server当前不支持该功能,是否有任何解决方法可以实现?
提前谢谢
解决方法
在使用Always Encrypted
的SQL Server版本System-Versioned Temporal Tables时。
您可以使表成为系统版本,并将维护历史记录的工作留给SQL Server引擎(同样,当您更改表设计时,引擎将减轻对历史记录表的更改)。
可以使用特殊子句queried来临时表,并为您提供分析历史数据的新方法。
我面临的一个缺点是,历史记录表的列必须与目标表的列相匹配-因此,如果您需要在历史记录中包含ModifiedBy
列,则必须更改应用程序以在原始表。