sql-server 始终加密-参数

ctehm74n  于 2022-10-31  发布在  其他
关注(0)|答案(1)|浏览(142)

我在服务器端为我的表列设置了“始终加密”。从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“列/变量'@val1'的加密方案不匹配。列/变量的加密方案为(encryption_type = 'PLAINTEXT'),而第'1'行附近的表达式要求它为DETERMINISTIC或PLAIN TEXT。
我做错了什么?

uqxowvwt

uqxowvwt1#

您不能对“始终加密”列使用局部变量,它们 * 必须 * 来自客户端参数。在SSMS中,它可以工作,因为SSMS会解析您的脚本并将变量提取到参数中,但在C++或其他客户端中,您必须自己将其参数化。
例如,下面的代码在Microsoft的网站上用作示例,请参阅那里了解有关如何使用“始终加密”的更多信息:

SQL_DATE_STRUCT date;
SQLLEN cbdate;   // size of date structure  

SQLCHAR SSN[12];
strcpy_s((char*)SSN, _countof(SSN), "795-73-9838");

SQLWCHAR* firstName = L"Catherine";
SQLWCHAR* lastName = L"Abel";
SQLINTEGER cbSSN = SQL_NTS, cbFirstName = SQL_NTS, cbLastName = SQL_NTS;

// Initialize the date structure  
date.day = 10;
date.month = 9;
date.year = 1996;

// Size of structures   
cbdate = sizeof(SQL_DATE_STRUCT);

SQLRETURN rc = 0;

string queryText = "INSERT INTO [dbo].[Patients] ([SSN], [FirstName], [LastName], [BirthDate]) VALUES (?, ?, ?, ?) ";

rc = SQLPrepare(hstmt, (SQLCHAR *)queryText.c_str(), SQL_NTS);

//SSN
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 11, 0, (SQLPOINTER)SSN, 0, &cbSSN);
//FirstName
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)firstName, 0, &cbFirstName);
//LastName
rc = SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_WCHAR, SQL_WCHAR, 50, 0, (SQLPOINTER)lastName, 0, &cbLastName);
//BirthDate
rc = SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_TYPE_DATE, SQL_TYPE_DATE, 10, 0, (SQLPOINTER)&date, 0, &cbdate);

rc = SQLExecute(hstmt);

正如您所看到的,SQLBindParameter用于向查询添加参数。您不能使用文本或SQL局部变量来插入加密列或与加密列进行比较,因为服务器无法访问解密数据。
客户端驱动程序需要能够访问相关证书。

相关问题