问题
I am unable to EXEC a stored procedure that upserts a table that has an encrypted column using Always Encrypted. However, I am able to copy the SQL from the sproc and run that as regular SQL with the parameters set, Just cannot get the sproc to fire when executing the sproc via the EXEC function in SSMS which is also causing problems in the application
The table has a trigger on it that inserts into another audit table of similar structure that is also encrypted using the same encryption. I have done the usual thing:
EXEC sp_refresh_parameter_encryption 'organization.uspOrganizationAddressUpsert'
Tables:
CREATE TABLE [organization].[OrganizationAddress](
[OrganizationAddressId] [int] IDENTITY(1,1) NOT NULL,
[CreatedUser] [int] NOT NULL,
[CreatedDate] [datetime2](7) NOT NULL,
[LastUpdateUser] [int] NOT NULL,
[LastUpdateDate] [datetime2](7) NOT NULL,
[RemovedDate] [datetime2](7) NULL,
[Address1] [varchar](60) NOT NULL,
[Address2] [varchar](60) NULL,
[City] [varchar](60) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
[State] [varchar](60) NOT NULL,
[ZipCode] [varchar](60) NOT NULL,
[ClientNumberId] [int] NOT NULL
CREATE TABLE [audit].[OrganizationAddressAudit](
[OrganizationAddressId] [int] NOT NULL,
[CreatedUser] [int] NOT NULL,
[CreatedDate] [datetime2](7) NOT NULL,
[LastUpdateUser] [int] NOT NULL,
[LastUpdateDate] [datetime2](7) NOT NULL,
[RemovedDate] [datetime2](7) NULL,
[Address1] [varchar](60) NOT NULL,
[Address2] [varchar](60) NULL,
[City] [varchar](60) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
[State] [varchar](60) NOT NULL,
[ZipCode] [varchar](60) NOT NULL,
[ClientNumberId] [int] NOT NULL,
[OperationDate] [datetime] NOT NULL,
[Operation] [varchar](50) NOT NULL,
[OperationBy] [varchar](100) NOT NULL
Stored Procedure:
ALTER PROCEDURE [organization].[uspOrganizationAddressUpsert]
@OrganizationId INT,
@ExecutingUserId INT,
@Address1 VARCHAR(60),
@Address2 VARCHAR(60),
@City VARCHAR(60),
@State VARCHAR(60),
@ZipCode VARCHAR(60),
@ClientNumberId INT
AS
BEGIN
SET NOCOUNT ON
DECLARE @RightNow AS DATETIME2 = SYSDATETIME()
If EXISTS (Select 1 From [organization].[OrganizationAddress] Where ClientNumberId = @ClientNumberId)
BEGIN
UPDATE [organization].[OrganizationAddress] SET
LastUpdateUser = @ExecutingUserId,
LastUpdateDate = @RightNow,
Address1 = @Address1,
Address2 = @Address2,
City = @City,
[State] = @State,
ZipCode = @ZipCode,
RemovedDate = Null
Where ClientNumberId = @ClientNumberId
END
ELSE
BEGIN -- INSERT part of the UPSERT
INSERT INTO [organization].[OrganizationAddress]
(CreatedUser
,CreatedDate
,LastUpdateUser
,LastUpdateDate
,Address1
,Address2
,City
,[State]
,ZipCode
,ClientNumberId)
VALUES
(@ExecutingUserId
,@RightNow
,@ExecutingUserId
,@RightNow
,@Address1
,@Address2
,@City
,@State
,@ZipCode
,@ClientNumberId)
END
END
Running the stored procedure code with the paramteers set is fine, but I am unable to EXEC the sproc:
declare @orgId INT = 1;
declare @client int = 888;
declare @user int = 1;
declare @Add1 varchar(60)= 'Test Address1';
declare @Add2 varchar(60)= 'Test Address2';
declare @city varchar(60) = 'City';
declare @state varchar(60) = 'St';
declare @zip varchar(60) = '12345';
EXEC organization.uspOrganizationAddressUpsert
@OrganizationID=@orgID,
@ExecutingUserId = @user, -- int
@Address1 = @Add1, -- varchar(60)
@Address2 = @Add2, -- varchar(60)
@City = @city, -- varchar(60)
@State = @state, -- varchar(60)
@ZipCode = @zip, -- varchar(60)
@ClientNumberId = @client; -- int
Msg 206, Level 16, State 2, Procedure uspOrganizationAddressUpsert, Line 0 [Batch Start Line 1]
Operand type clash: varchar is incompatible with varchar(60) 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 = 'BankruptcyApp') collation_name = 'SQL_Latin1_General_CP1_CI_AS'
I created a similar table in a test DB with VARCHAR(60) for the enrcrypted columns, a trigger, and an audit table and its working fine there and I cant find any differences in the table/sproc/trigger that would allow it to work there and not here. I've pretty much exhausted the other posts and blogs I can find.
回答1:
Fixed! Needed to update the app code to specify the data type and length:
parameters.Add("@City", organizationAddress.City, System.Data.DbType.AnsiString, System.Data.ParameterDirection.Input, 60);
where it was previously just:
parameters.Add("@City", organizationAddress.City)
This at least get the app to run the sproc but still cant run it from SSMS via EXEC
来源:https://stackoverflow.com/questions/47415873/sql-server-always-encrypted-operand-type-clash-varchar-is-incompatible-with-var