I have the following problem: for a new project with Windows Forms C++/CLI I used my existing class for the MySQL connection with the ConnectorC++ 8.2.
However, in this project I now have the problem that both queries from the database and the insertion cause problems if there is an umlaut in the string.
I do not have this problem (with the same MySQL connection class of mine) in other projects of mine.
To clarify: I have a table with 4 columns: ID, number, number, name.
I now select the data from the table via PreparedStatements.
As long as there are no umlauts (ö ä ü) everything is fine, but as soon as an umlaut appears there are the following problems, among others:
test2 "öÄ üÜ äÄ Test irgendwas" std::string
But if I test something in the code like:
std::string test5 = "äÄ";
test5 "äÄ" std::string
it also recognizes it and displays it correctly.
This problem only occurs when I work with the database - in all other places umlauts are displayed or recognized correctly.
Does anyone have an idea what the reason could be that it causes such problems explicitly with this project?
I have already tried to set explicit to utf8 for the project itself when creating the connection:
_connection->setClientOption("character_set_client", "utf8");
_connection->setClientOption("character_set_connection", "utf8");
_connection->setClientOption("character_set_results", "utf8");
I also checked the settings of the project and changed it to "Not Set" under "Properties" -> "Configuration Properties" -> "Advance" -> "Character Set".
I also tried once to convert a std::string to std::wstring, which then displayed the umlauts correctly. Converting it back to a std::string then caused the same problems again.
#include "MainForm.h"
#include <jdbc/mysql_driver.h>
#include <jdbc/mysql_connection.h>
#include <jdbc/cppconn/prepared_statement.h>
#include <jdbc/cppconn/resultset.h>
#include <jdbc/cppconn/statement.h>
TestProject::MainForm::MainForm()
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
LoadMainWindowDataFromDatabase();
}
void TestProject::MainForm::LoadMainWindowDataFromDatabase()
{
sql::mysql::MySQL_Driver* driver;
driver = sql::mysql::get_mysql_driver_instance();
sql::Connection* connection;
try
{
connection = driver->connect("localhost:3306", "user", "Password");
// Select the database
connection->setSchema("db_47739_7");
connection->setClientOption("character_set_client", "utf8");
connection->setClientOption("character_set_connection", "utf8");
connection->setClientOption("character_set_results", "utf8");
}
catch (sql::SQLException& e)
{
std::string errorMessage = "MySQL-Error: ";
errorMessage += e.what();
return;
}
catch (std::exception& e)
{
std::string errorMessage = "MySQL - Error: : ";
errorMessage += e.what();
return;
}
catch (...)
{
std::string errorMessage = "MySQL - Error: OpenMySQLConnection - Unknown exception caught.";
return;
}
std::string query = "SELECT sahq.ArticleID, sahq.Quantity, ad.Manufacturer, ad.ArticleNumber, ad.ArticleName FROM storage_article_history_quantity AS sahq JOIN article_database AS ad ON sahq.ArticleID = ad.ID ORDER BY sahq.quantity DESC LIMIT 10 ";
sql::PreparedStatement* preQuery = connection->prepareStatement(query);
sql::ResultSet* result = preQuery->executeQuery();
if (!result)
return;
sql::ResultSetMetaData* metaData = result->getMetaData();
int numCols = metaData->getColumnCount();
std::vector<std::vector<std::string>> data;
data.clear();
/*
// int int string string string
SELECT sahq.ArticleID, sahq.Quantity, ad.Manufacturer, ad.ArticleNumber, ad.ArticleName
FROM storage_article_history_quantity AS sahq JOIN article_database AS ad ON sahq.ArticleID = ad.ID ORDER BY sahq.quantity DESC LIMIT 10
*/
while (result->next())
{
std::vector<std::string> rowData;
for (int col = 1; col <= numCols; ++col)
{
std::string cellValue;
if (col == 1 || col == 2)
cellValue = std::to_string(result->getInt(col));
else
cellValue = result->getString(col);
if (col == 5)
{
std::string test2 = result->getString(5);
sql::SQLString test4 = result->getString(5);
std::string test5;
test5 = "äÄ";
}
}
}
}
mainForm.h
#pragma once
#include <vector>
namespace TestProject {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for MainForm
/// </summary>
public ref class MainForm : public System::Windows::Forms::Form
{
public:
MainForm();
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~MainForm()
{
if (components)
{
delete components;
}
}
private:
void LoadMainWindowDataFromDatabase();
private: System::Windows::Forms::DataGridView^ dataGridView1;
protected:
private: System::Windows::Forms::Button^ button1;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->dataGridView1 = (gcnew System::Windows::Forms::DataGridView());
this->button1 = (gcnew System::Windows::Forms::Button());
(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->dataGridView1))->BeginInit();
this->SuspendLayout();
//
// dataGridView1
//
this->dataGridView1->ColumnHeadersHeightSizeMode = System::Windows::Forms::DataGridViewColumnHeadersHeightSizeMode::AutoSize;
this->dataGridView1->Location = System::Drawing::Point(57, 257);
this->dataGridView1->Name = L"dataGridView1";
this->dataGridView1->Size = System::Drawing::Size(518, 150);
this->dataGridView1->TabIndex = 0;
//
// button1
//
this->button1->Location = System::Drawing::Point(314, 71);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 1;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
//
// MainForm
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(666, 456);
this->Controls->Add(this->button1);
this->Controls->Add(this->dataGridView1);
this->Name = L"MainForm";
this->Text = L"MainForm";
(cli::safe_cast<System::ComponentModel::ISupportInitialize^>(this->dataGridView1))->EndInit();
this->ResumeLayout(false);
}
#pragma endregion
};
}
main.cpp
#pragma once
#include "MainForm.h"
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Reflection;
int main2(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
Application::Run(gcnew TestProject::MainForm());
return 0;
}
I tried to make it as small as possible. Also in this version the string from the database is not correctly converted to UTF-8. It is a CLR Empty Project(.Net Framework) with .Net Framework 4.8