Always Encrypted SQL Server : How to insert / updated using C++ code?
-1
votes
2
answers
898
views
I have set the Always Encrypted option to my table columns.
Now I need to insert or update my table from my C++ Client application.
I know that we need to declare params and use them for Always Encrypted.
From SSMS I am able to do so without any issues.
However, when I try using C++ code, it fails.
Say, for example, my table contains two columns that have data type int.
I connect to my database using the below connection string:
"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=;";
I create the below SQL query string:
CString csQStrInsert = L"declare @val1 int = 3; declare @val2 int = 3; insert into [dbo].[Table_AlwaysEncrypted] ([col1], [col2]) values (@val1, @val2);";
And call
pDatabase->ExecuteSQL(csQStrInsert);
However, this throws exception with the following info:
*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.*
Can someone help me out? There is mostly no help when it comes to C++ code for Always Encrypted.
[Trialed code that still fails in SQL Execute:]
SQLHENV henv = SQL_NULL_HENV;
SQLHDBC hdbc1 = SQL_NULL_HDBC;
SQLHSTMT hstmt = SQL_NULL_HSTMT;
SQLRETURN rc = 0;
RETCODE retcode;
retcode = SQLAllocHandle(SQL_HANDLE_ENV, NULL, &henv);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_IS_INTEGER); // Notify ODBC that this is an ODBC 3.0 app.
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
retcode = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc1); // Allocate ODBC connection handle and connect.
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
SQLCHAR retconstring;
SQLWCHAR connstr[] = L"Driver={ODBC Driver 17 for SQL Server};Server=192.168.555.128,1433;Encrypt=no;Trusted_Connection=no;ColumnEncryption=Enabled;DATABASE=AEncrypted;UID=Supervisor;PWD=;";
retcode = SQLDriverConnect(hdbc1, NULL, connstr, SQL_NTS, (SQLWCHAR*)retconstring, 1024, NULL, SQL_DRIVER_NOPROMPT);
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
SQLWCHAR sqlstate;
SQLWCHAR message;
if (SQL_SUCCESS == SQLGetDiagRec(SQL_HANDLE_DBC, hdbc1, 1, sqlstate, NULL, message, 1024, NULL))
{
CString csMsg = message;
}
retcode = SQLAllocHandle(SQL_HANDLE_STMT, hdbc1, &hstmt); // Allocate statement handle.
if (retcode == SQL_SUCCESS || retcode == SQL_SUCCESS_WITH_INFO)
{
//
}
}
}
}
}
std::string queryText = "INSERT INTO [dbo].[Table_AEncrypted] ([col1], [col2]) VALUES (?, ?);";
rc = SQLPrepare(hstmt, (SQLWCHAR *)queryText.c_str(), SQL_NTS);
SQLINTEGER val1 = 123;
SQLINTEGER val2 = 456;
SQLINTEGER cbNull = SQL_NULL_DATA;
rc = SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, SQL_DESC_PRECISION, 0, (SQLPOINTER)val1, 0, &cbNull);
rc = SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, SQL_DESC_PRECISION, 0, (SQLPOINTER)val2, 0, &cbNull);
rc = SQLExecute(hstmt);
// Clean up.
SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
SQLDisconnect(hdbc1);
SQLFreeHandle(SQL_HANDLE_DBC, hdbc1);
SQLFreeHandle(SQL_HANDLE_ENV, henv);
Asked by Amal Jesudas
(69 rep)
Oct 26, 2022, 10:03 PM
Last activity: Nov 7, 2022, 03:11 PM
Last activity: Nov 7, 2022, 03:11 PM