SQL Server Always Encrypted Operand type clash: varchar is incompatible with varchar(60) when running EXEC sproc

元气小坏坏 提交于 2019-12-11 03:33:53

问题


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:

  • Checking the Enable Parameterizaion for Always Encrypted in Query Options
  • Setting column encryption setting=enabled on the Connection Settings.
  • Refreshing the encyrption metadata for the sproc:
        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

  • 易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
    该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!