You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已配置Always Encrypted,C++客户端插入数据遇加密方案不匹配错误求助

问题描述

已在服务器端为表列配置Always Encrypted,使用C++客户端时,通过以下连接字符串连接数据库:

CString connString = L"Driver={ODBC Driver 17 for SQL Server};Server=192.122.200.200,1433;Encrypt=no;Trusted_Connection=no;ColumnEncryption=Enabled;DATABASE=AlwaysEncrypted;UID=sa;PWD=;";

执行以下插入数据的命令时失败:

CString csQStrInsert = L"declare @val1 int = 3; declare @val2 int = 3; insert into [dbo].[Table_AlwaysEncrypted] ([col1], [col2]) values (@val1, @val2);";

pDatabase->ExecuteSQL(csQStrInsert);

报错信息:

pEX->m_strError = L"Encryption scheme mismatch for columns/variables '@val1'. The encryption scheme for the columns/variables is (encryption_type = 'PLAINTEXT') and the expression near line '1' expects it to be DETERMINISTIC, or PLAIN TEXT.

问题原因与解决方法
  • 问题根源:你在SQL脚本里直接声明并赋值变量,这些变量是在服务器端以明文形式存在的。而Always Encrypted的核心逻辑是客户端加密——只有客户端能处理明文数据,服务器只能存储加密后的内容,无法直接接收明文变量插入加密列。

  • 正确做法:使用参数化查询,不要在SQL语句里声明变量,而是把参数值传递给驱动,让ODBC驱动在客户端完成加密后再发送给服务器。示例代码如下:

// 准备参数化的插入语句
CString csQStrInsert = L"insert into [dbo].[Table_AlwaysEncrypted] ([col1], [col2]) values (?, ?);";

// 创建参数化命令对象(基于ODBC标准流程)
SQLHSTMT hStmt;
SQLAllocHandle(SQL_HANDLE_STMT, pDatabase->m_hdbc, &hStmt);
SQLPrepare(hStmt, (SQLWCHAR*)csQStrInsert.GetString(), SQL_NTS);

// 绑定参数1,值为3
int val1 = 3;
SQLBindParameter(hStmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &val1, 0, NULL);

// 绑定参数2,值为3
int val2 = 3;
SQLBindParameter(hStmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &val2, 0, NULL);

// 执行语句
SQLExecute(hStmt);

// 释放资源
SQLFreeHandle(SQL_HANDLE_STMT, hStmt);

这样驱动会自动识别目标列的加密配置,在客户端对参数值进行加密,再将密文发送到服务器,避免了服务器处理明文的情况,也就不会触发加密方案不匹配的错误。

内容的提问来源于stack exchange,提问作者Amal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:41:26