Sql server MS-SQL-ODBC-INSERT在应用于“数据库”时失败;“始终加密”;VARCHAR(最大)列 标题##MS-SQL-ODBC-INSERT应用于“始终加密”VARCHAR(MAX)列时失败

Sql server MS-SQL-ODBC-INSERT在应用于“数据库”时失败;“始终加密”;VARCHAR(最大)列 标题##MS-SQL-ODBC-INSERT应用于“始终加密”VARCHAR(MAX)列时失败,sql-server,odbc,Sql Server,Odbc,以下程序尝试使用ODBC将文本文件加载到VARCHAR(max)列中。 VARCHAR(MAX)列是加密的-使用“始终加密”功能 create table clobTable ( id integer identity(1,1) primary key not null, --clobCol varchar(max) clobCol [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY =

以下程序尝试使用ODBC将文本文件加载到VARCHAR(max)列中。 VARCHAR(MAX)列是加密的-使用“始终加密”功能

create table clobTable
(
id integer identity(1,1) primary key not null,
--clobCol varchar(max)
clobCol [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK1], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL
);
INSERT语句在执行时失败,同时通知以下错误消息:

Native error = 206
Message text = [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Operand type clash: varchar(max) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK1', column_encryption_key_database_name = 'AEdemo') collation_name = 'Compatibility_136_8200_0' is incompatible with varchar(max) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK1',
SQLState     = 37000
Native error = 8180
Message text = [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Statement(s) could not be prepared.
注:

  • 在VARCHAR(MAX)列所在的表上应用此程序时 没有加密-它工作得非常好
  • 以下内容通过MS-SQL server management studio发布,运行良好:
  • 
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    /*
    MS-SQL-ODBC-INSERT在“始终加密”VARCHAR(MAX)列上应用时失败
    以下程序尝试使用ODBC将文本文件加载到VARCHAR(max)列中。
    VARCHAR(MAX)列是加密的-使用“始终加密”功能。
    创建表clobTable
    (
    id整数标识(1,1)主键不为空,
    --clobCol varchar(最大值)
    clobCol[varchar](最大值)使用(列加密密钥=[CEK1],加密类型=确定性,算法='AEAD\U AES\U 256\U CBC\U HMAC\U SHA\U 256')空值对拉丁1\U常规\U BIN2加密
    );
    INSERT语句在执行时失败,同时通知以下错误消息:
    SQLState=22005
    本机错误=206
    消息文本=[Microsoft][ODBC Driver 17 for SQL Server][SQL Server]操作数类型冲突:使用(加密类型='DETERMINISTIC',加密算法\名称='AEAD\ U AES\ U 256\ CBC\ U HMAC\ U SHA\ U 256',列加密\密钥\名称='CEK1',列加密\密钥\数据库\名称='AEdemo')排序规则\u名称='Compatibility\u 136\u 8200\u 0'与使用(encryption\u type='DETERMINISTIC',encryption\u algorithm\u name='AEAD\u AES\u 256\u CBC\u HMAC\u SHA\u 256',列\u encryption\u key\u name='CEK1'加密的varchar(max)不兼容,
    SQLState=37000
    本机错误=8180
    消息文本=[Microsoft][ODBC驱动程序17 for SQL Server][SQL Server]语句无法准备。
    笔记:
    1.当在VARCHAR(MAX)列未加密的表上应用此程序时,它工作得非常好。
    2.以下通过MS-SQL server management studio发布,运行良好:
    声明@v varchar(max)='11111111111111122222222222233333333333333344444444444444'
    插入可克隆(clobCol)值(@v)
    */
    #定义uuu CON_ustr_uuuuu“DRIVER={ODBC DRIVER 17 for SQL Server};Server=sql16-w16.qa.int\\mssqlserver2016;Database=AEdemo;UID=xx;PWD=yyyyyyyyy;columnecryption=Enabled;”
    #定义文件“.\\DevProjects\\mssql将文件加载到varchar max\\big text FILE.txt”
    静态int SQL_OK(SQLRETURN结果);
    静态int打印错误(SQLHENV envHandle、SQLHDBC conHandle、SQLHSTMT stmtHandle);
    静态char*loadedFile(char*pszTheFile);
    int main(int argc,char*argv[])
    {
    char*pszBigString=NULL;
    const char*pszSQL=“插入clobTable(clobCol)值(?);
    HSTMT HSTMT=NULL;
    SQLHENV-hEnv=NULL;
    SQLRETURN iError=SQLAllocEnv(&hEnv);
    SQLLEN*len;
    HDBC HDBC=NULL;
    SQLAllocConnect(hEnv和hDbc);
    const char*pszConnStr=\uuu CON\u STR;
    UCHAR szConnectOut[SQL_MAX_MESSAGE_LENGTH];
    剑I连接线=0;
    iError=SQLDriverConnectA(hDbc,NULL,(无符号字符*)pszConnStr,
    SQL\n、szConnectOut、,
    (SQL_MAX_MESSAGE_LENGTH-1)和iConnectOutLen,
    SQL(驱动程序完成);
    如果(!SQL_OK(iError))
    {
    打印错误(SQL\u NULL\u HENV、hDbc、SQL\u NULL\u HSTMT);
    出口(-1);
    }
    iError=SQLAllocStmt(hDbc和hStmt);
    iError=SQLPrepareA(hStmt,(SQLCHAR*)pszSQL,SQL_NTS);
    如果(!SQL_OK(iError))
    {
    打印错误(SQL\u NULL\u HENV、SQL\u NULL\u HDBC、hStmt);
    出口(-1);
    }
    pszBigString=loadedFile(uuu文件);//u文件uu;
    len=strlen(pszBigString);
    iError=SQLSetParam(hStmt,1,SQL_C_CHAR,SQL_VARCHAR,0,0,(SQLPOINTER)pszBigString,NULL);
    iError=SQLExecute(hStmt);
    如果(!SQL_OK(iError))
    {
    打印错误(SQL\u NULL\u HENV、SQL\u NULL\u HDBC、hStmt);
    出口(-1);
    }
    iError=SQLDisconnect(hDbc);
    如果(!SQL_OK(iError))
    {
    打印错误(SQL\u NULL\u HENV、hDbc、SQL\u NULL\u HSTMT);
    出口(-4);
    }
    SQLFreeHandle(SQL\u HANDLE\u STMT,hStmt);
    sqlfreehold(SQL\u HANDLE\u DBC,hDbc);
    sqlfreehold(SQL\u HANDLE\u ENV,hEnv);
    }
    静态/*bool*/int SQL\u OK(SQLRETURN结果)
    {
    if(result==SQL_SUCCESS | | result==SQL_SUCCESS_WITH_INFO)
    返回(真);
    其他的
    返回(假);
    }
    静态/*bool*/int打印错误(SQLHENV envHandle,
    SQLHDBC-conHandle,
    SQLHSTMT stmtHandle)
    {
    返回结果;
    SQLWCHAR-sqlState[6];
    SQLINTEGER-nativeError;
    SQLSMALLINT所需长度;
    SQLWCHAR messageText[1024+1];
    做
    {
    结果=SQLError(envHandle,
    康汉德尔,
    斯姆坦德尔,
    sqlState,
    &国家错误,
    messageText,
    sizeof(messageText),
    &所需长度);
    如果(SQL_正常(结果))
    {
    printf(“SQLState=%S\n”,SQLState);
    printf(“本机错误=%d\n”,本机错误);
    printf(“消息文本=%S\n”,消息文本);
    }
    }而(SQL_OK(结果));
    返回0;
    }
    #包括
    #包括
    静态char*loadedFile(char*pszTheFile)
    {
    结构统计;
    国际统计局;
    _关闭文件大小=0;
    char*pszFileContents;
    文件*fp;
    memset(&st,0,sizeof(st));
    statRes=stat(pszTheFile,&st);
    如果(statRes==0)
    fileSize=st.st\u size;
    其他的
    返回NULL;
    pszFileContents=calloc(1,文件大小);
    fp=fopen(pszTheFile,“r”);
    fread(pszFileContents,1,fileSize,fp);
    fclose(fp);
    返回pszFileContents;
    }
    
    2020-02-13

    引用的文档帮助不大。
    然而,在引用的URL之后,“使用始终加密的SQL Server ODBC驱动程序”显示
    declare @v varchar(max) = '111111111111111111222222222222222222222223333333333333333333333334444444444444444'
    insert into clobTable (clobCol) values (@v)
    
    
    #include <windows.h>
    #include <sql.h>
    #include <sqlext.h>
    #include <sqltypes.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    /*
    
    MS-SQL - ODBC - INSERT fails when applied on an "Always Encrypted" VARCHAR(MAX) column
    
    The following program attempts to load a text file into a VARCHAR(max) column - using ODBC.
    The VARCHAR(MAX) column is encrypted - using 'Always Encrypted' feature.
    
    create table clobTable
    (
    id integer identity(1,1) primary key not null,
    --clobCol varchar(max)
    clobCol [varchar](max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK1], ENCRYPTION_TYPE = Deterministic, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NULL
    );
    
    The INSERT statement fails upon execution while informing the following error message:
    
    SQLState     = 22005
    Native error = 206
    Message text = [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Operand type clash: varchar(max) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK1', column_encryption_key_database_name = 'AEdemo') collation_name = 'Compatibility_136_8200_0' is incompatible with varchar(max) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK1',
    SQLState     = 37000
    Native error = 8180
    Message text = [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Statement(s) could not be prepared.
    
    Notes:
    1. When applying this program on a table in which VARCHAR(MAX) column is not encrypted - it works perfectly fine.
    2. Following is issued via MS-SQL server management studio and it works fine:
    
    declare @v varchar(max) = '111111111111111111222222222222222222222223333333333333333333333334444444444444444'
    insert into clobTable (clobCol) values (@v)
    
    
    */
    
    #define __CON_STR__  "DRIVER={ODBC Driver 17 for SQL Server};Server=sql16-w16.qa.int\\mssqlserver2016;Database=AEdemo;UID=xx;PWD=yyyyyyyy;ColumnEncryption=Enabled;"
    #define __THE_FILE__     "..\\DevProjects\\mssql-load-file-to-varchar-max\\big-text-file.txt"
    
    
    static int SQL_OK(SQLRETURN result);
    static int printErrors(SQLHENV  envHandle, SQLHDBC  conHandle, SQLHSTMT stmtHandle);
    static char * loadedFile(char *pszTheFile);
    
    int main(int argc, char * argv[])
    {
        char* pszBigString = NULL;
        const char* pszSQL = "INSERT INTO clobTable (clobCol) VALUES (?)";
        HSTMT hStmt = NULL;
        SQLHENV hEnv = NULL;
        SQLRETURN iError = SQLAllocEnv(&hEnv);
        SQLLEN *        len;
    
        HDBC hDbc = NULL;
        SQLAllocConnect(hEnv, &hDbc);
    
        const char* pszConnStr = __CON_STR__;
        UCHAR szConnectOut[SQL_MAX_MESSAGE_LENGTH];
        SWORD iConnectOutLen = 0;
        iError = SQLDriverConnectA(hDbc, NULL, (unsigned char*)pszConnStr,
            SQL_NTS, szConnectOut,
            (SQL_MAX_MESSAGE_LENGTH - 1), &iConnectOutLen,
            SQL_DRIVER_COMPLETE);
    
        if (!SQL_OK(iError))
        {
            printErrors(SQL_NULL_HENV, hDbc, SQL_NULL_HSTMT);
            exit(-1);
        }
    
        iError = SQLAllocStmt(hDbc, &hStmt);
    
        iError = SQLPrepareA(hStmt, (SQLCHAR*)pszSQL, SQL_NTS);
        if (!SQL_OK(iError))
        {
            printErrors(SQL_NULL_HENV, SQL_NULL_HDBC, hStmt);
            exit(-1);
        }
    
        pszBigString =  loadedFile(__THE_FILE__); // __THE_FILE__;
        len = strlen(pszBigString);
    
        iError = SQLSetParam(hStmt, 1, SQL_C_CHAR, SQL_VARCHAR, 0, 0, (SQLPOINTER)pszBigString, NULL);
    
        iError = SQLExecute(hStmt); 
        if (!SQL_OK(iError))
        {
            printErrors(SQL_NULL_HENV, SQL_NULL_HDBC, hStmt);
            exit(-1);
        }
    
        iError = SQLDisconnect(hDbc);
        if (!SQL_OK(iError))
        {
            printErrors(SQL_NULL_HENV, hDbc, SQL_NULL_HSTMT);
            exit(-4);
        }
    
        SQLFreeHandle(SQL_HANDLE_STMT, hStmt);
        SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
        SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
    
    }
    
    static /*bool*/ int SQL_OK(SQLRETURN result)
    {
        if (result == SQL_SUCCESS || result == SQL_SUCCESS_WITH_INFO)
            return(TRUE);
        else
            return(FALSE);
    }
    
    
    static /*bool*/ int printErrors(SQLHENV  envHandle,
        SQLHDBC  conHandle,
        SQLHSTMT stmtHandle)
    {
        SQLRETURN   result;
        SQLWCHAR    sqlState[6];
        SQLINTEGER  nativeError;
        SQLSMALLINT requiredLength;
        SQLWCHAR    messageText[1024 + 1];
    
        do
        {
            result = SQLError(envHandle,
                conHandle,
                stmtHandle,
                sqlState,
                &nativeError,
                messageText,
                sizeof(messageText),
                &requiredLength);
    
            if (SQL_OK(result))
            {
                printf("SQLState     = %S\n", sqlState);
                printf("Native error = %d\n", nativeError);
                printf("Message text = %S\n", messageText);
            }
        } while (SQL_OK(result));
    
        return 0;
    }
    
    
    #include <sys/stat.h>
    #include <sys/types.h>
    static char * loadedFile(char *pszTheFile)
    {
        struct stat st;
        int statRes;
        _off_t fileSize = 0;
        char *pszFileContents;
        FILE *fp;
    
        memset(&st, 0, sizeof(st));
    
        statRes = stat(pszTheFile, &st);
        if (statRes == 0)
            fileSize = st.st_size;
        else
            return NULL;
    
        pszFileContents = calloc(1, fileSize);
    
        fp = fopen(pszTheFile, "r");
        fread(pszFileContents, 1, fileSize, fp);
        fclose(fp);
    
        return pszFileContents;
    
    }
    
    iError = SQLGetConnectAttr(hDbc, SQL_COPT_SS_COLUMN_ENCRYPTION, (SQLPOINTER)&uIntVal, (SQLINTEGER) sizeof(uIntVal), NULL);
    if (!SQL_OK(iError))
    {
       printErrors(SQL_NULL_HENV, hDbc, SQL_NULL_HSTMT);
       exit(-1);
    }
    else
    {
      printf("\nConnection attribute SQL_COPT_SS_COLUMN_ENCRYPTION value is : %d", uIntVal);
    }
    
    Connection attribute SQL_COPT_SS_COLUMN_ENCRYPTION value is : 1