sql-server - SQL Server 始终加密 : Operand type clash: varchar is incompatible with varchar(max)

标签 sql-server encryption always-encrypted

由于英国即将实现监管变更,我正在开发的数据库需要更新,以对任何个人身份信息进行加密。

我的许多表已成功更改,但是在某些存在触发器的表上,我收到以下错误。

Error SQL72014: .Net SqlClient Data Provider: Msg 206, Level 16, State 2, Procedure tr_Employee_Update, Line 27 Operand type clash: varchar is incompatible with varchar(max) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'xxxx') collation_name = 'Latin1_General_BIN2'

我在这里查看了这个问题,但这并不能解决我的问题 Operand type clash: varchar is incompatible with varchar(50) trying to insert in encrypted database

与这个问题也一样,哪里没有完全解决我的问题。 SQL Server Always Encrypted Operand type clash: varchar is incompatible with varchar(60) when running EXEC sproc .

我在很多 table 上都遇到了这个问题,因此非常感谢您的帮助。

请在此处查看 SQL Fiddle

http://sqlfiddle.com/#!18/4ac5c/3

我不得不拆分表并创建触发器,因为 SQL 长度大于 8000 个字符,但这是我能给出的最完整的示例。

我使用加密类型:确定性和加密 key 名称:CEK_Auto1 对列进行加密。

并非该表中的所有列都需要加密,并且我正在更改其他一些具有默认值的字段,这些字段也需要进行加密。

对于所报告问题的任何及所有帮助,我们将不胜感激。

CREATE TABLE [dbo].[Employee] (
[EmployeeID]        INT           IDENTITY (1, 1) NOT NULL,
[EmployeeTypeID]    INT           NOT NULL,
[Title]             VARCHAR (50)  NOT NULL,
[Forename]          VARCHAR (30)  NOT NULL,
[Surname]           VARCHAR (30)  NOT NULL,
[AddressLine1]      VARCHAR (60)  NOT NULL,
[AddressLine2]      VARCHAR (60)  NOT NULL,
[AddressLine3]      VARCHAR (60)  NOT NULL,
[AddressLine4]      VARCHAR (60)  NOT NULL,
[Town]              VARCHAR (50)  NOT NULL,
[County]            VARCHAR (50)  NOT NULL,
[PostCode]          VARCHAR (20)  NOT NULL,
[Phone]             VARCHAR (20)  CONSTRAINT [DF_Employee_Phone] DEFAULT ('') NOT NULL,
[Mobile]            VARCHAR (20)  NOT NULL,
[Fax]               VARCHAR (20)  NOT NULL,
[Email]             VARCHAR (50)  NOT NULL,
[Extension]         VARCHAR (10)  CONSTRAINT [DF_Employee_Extension_1] DEFAULT ('') NOT NULL,
[SpeedDial]         VARCHAR (10)  CONSTRAINT [DF_Employee_SpeedDial_1] DEFAULT ('') NOT NULL,
[Notes]             VARCHAR (MAX) NOT NULL,
[EmployeeTeamID]    INT           NULL,
[Created]           DATETIME      CONSTRAINT [DF_Employee_Created] DEFAULT (getdate()) NOT NULL,
[OperatorIDCreated] INT           NOT NULL,
[Updated]           DATETIME      CONSTRAINT [DF_Employee_Updated] DEFAULT (getdate()) NOT NULL,
[OperatorIDUpdated] INT           NOT NULL,
[Deleted]           BIT           CONSTRAINT [DF_Employee_Deleted] DEFAULT ((0)) NOT NULL,
[EmployeeIDManager] INT           NULL,
[JobTitle]          VARCHAR (100) CONSTRAINT [DF_Employee_JobTitle] DEFAULT ('') NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED ([EmployeeID] ASC),
CONSTRAINT [FK_Employee_Employee] FOREIGN KEY ([EmployeeIDManager]) REFERENCES [dbo].[Employee] ([EmployeeID]),
CONSTRAINT [FK_Employee_EmployeeTeam] FOREIGN KEY ([EmployeeTeamID]) REFERENCES [dbo].[EmployeeTeam] ([EmployeeTeamID]),
CONSTRAINT [FK_Employee_EmployeeType] FOREIGN KEY ([EmployeeTypeID]) REFERENCES [dbo].[EmployeeType] ([EmployeeTypeID])
);


GO
CREATE NONCLUSTERED INDEX [IX_Employee_Surname]
ON [dbo].[Employee]([Surname] ASC);


GO

CREATE TABLE [dbo].[AuditItem](
[AuditItemID] [INT] IDENTITY(1,1) NOT NULL,
[ID] [INT] NOT NULL,
[AuditEntityID] [INT] NOT NULL,
[AuditTypeID] [INT] NOT NULL,
[Note] [VARCHAR](MAX) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
[Created] [DATETIME] NOT NULL,
[OperatorIDCreated] [INT] NOT NULL,
[ProfessionalIDCreated] [INT] NULL,
 CONSTRAINT [PK_AuditItem] PRIMARY KEY CLUSTERED 
(
[AuditItemID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

    ALTER Trigger  [dbo].[tr_Employee_Update] ON [dbo].[Employee] 
FOR UPDATE

AS

--Audit Entity ID for Employees
Declare @AuditEntityID int
set @AuditEntityID = 2

Insert AuditItem
    (ID,AuditEntityID,AuditTypeID, Note, Created, OperatorIDCreated)
Select
    inserted.EmployeeID,
    @AuditEntityID,
    --Update type
    2,
    'Name changed from ' + ltrim(rtrim(ltrim(rtrim(Deleted.Title)) + ' ' + ltrim(rtrim(Deleted.Forename)) + ' ' + ltrim(rtrim(Deleted.Surname)))) + ' to ' + + ltrim(rtrim(ltrim(rtrim(Inserted.Title)) + ' ' + ltrim(rtrim(Inserted.Forename)) + ' ' + ltrim(rtrim(Inserted.Surname)))),
    GetDate(),
    inserted.OperatorIDUpdated
From inserted
        Inner Join deleted on inserted.EmployeeID = deleted.EmployeeID
Where deleted.Title <> inserted.Title or deleted.Forename <> inserted.Forename or deleted.Surname <> inserted.Surname

最佳答案

经过今天的大量研究,不幸的是,无论数据类型如何,目前都不支持触发器更新加密列。因此,任何偶然发现这个问题并且遇到同样问题的人都需要通过存储过程完成更新,但需要通过应用程序代码调用它们。

虽然我上面的问题中的两个链接问题没有直接解决我的问题或帮助我,但如果您需要将参数化值传递给存储过程并遇到问题,您可能需要遵循问题中的答案来帮助您。

关于sql-server - SQL Server 始终加密 : Operand type clash: varchar is incompatible with varchar(max),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50344374/

相关文章:

sql-server - SQL Server 标识列插入失败

security - 检查密码复杂度 : different from last X passwords

c++ - 如何解密xxtea?

java - 更改加密 key 后,适用于 Java 的 Microsoft JDBC 驱动程序无法找到 Azure Always Encrypted 列加密 key

sql-server - MERGE 查询和删除记录

mysql - 如果第一个parent_id级别> 1而不是id级别,则生成值为1的列

sql - FULL OUTER JOIN有点内

security - 避免重复的相同消息在加密后看起来总是相同的,并且可以被攻击者重放吗?

c# - 无法使用 Linq 插入到 SQL Server Always Encrypted 表中

sql-server - SQL 2016 无法创建列主 key