c++ dev , mysql Bind_placeholders.bind with single quotes - c++

I'm learning c++ web develoment .
I what save my data by MySql database .
my env
Apple M1
Docker Debian 11 Arm64
"Mysql8" and "MySQL Connector/C++ 8"
My question
I don't know how to use parameterized query .
my error code ①
SqlStatement sqlStatement = session.sql("SELECT * FROM ?.?")
.bind(nameless_carpool, user);
SqlResult sqlResult = sqlStatement.execute();
/*
I guses the api will got sql is :
SELECT * FROM ?.? -> SELECT * FROM 'nameless_carpool'.'user'
In fact error message :
terminate called after throwing an instance of 'mysqlx::abi2::r0::Error'
what(): CDK Error: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near ''nameless_carpool'.'user'' at line 1
*/
My right code ②
SqlStatement sqlStatement = session.sql("SELECT * FROM nameless_carpool.user");
SqlResult sqlResult = sqlStatement.execute();
/*
use the code , i can get my table info .
but i want use parameterized query
*/
Will anyone help me ?

slack friend Nik told me :
I don't think that will work. Using ? will escape the values as values, not for table names. Typically, you would use parameterized queries for values only.
For example, as you have seen, this doesn't work:
SELECT * FROM 'nameless_carpool'.'user'
It should be this:
SELECT * FROM `nameless_carpool`.`user`
But this is not what parameterized queries are typically for. It would be used for values, eg:
SELECT * FROM `nameless_carpool`.`user` WHERE `driver_name` = ?
which would turn into something like:
SELECT * FROM `nameless_carpool`.`user` WHERE `driver_name` = 'Wukong'
I know this from working with MySQL and other databases. It is not common to need a variable to reference a table. If you do, the application should handle this without directly taking user input

Related

Why is this SQL query not seem to be failing but actually failing?

I am adding a logger class to my web server and noticed that my logs are not being inserted although the query does not return a failure value.
This is my database handler class's query executer function:
//_mysql = MYSQL*
bool DatabaseConnection::query(const std::string &query) const {
return _mysql && 0 == mysql_real_query(_mysql, query.c_str(), query.length());
}
And this is the SQL query I attempted to execute:
insert into user_logs (id, action, when) value (1, 2, 1615856674);
When the C++ program executed this query it returned success however did not actually insert the row. So, I tried to manually execute it via a client and the query failed by telling me to wrap when with `.
After that the query worked as expected both in the client's console and in the C++ program.
I wonder why did it not fail in the C++ program?
"When the C++ program executed this query it returned success however did not actually insert the row."
It depdens on the client your C++ program is using. It might have simply swallowed the exeption and gives you the impression that it succeeded while it's not. To figure out why, you will need to dig into the C++ mysql client's source code.
When you try to execute queries using C++ code, try removing the terminating semicolon ;.
As an example, will not work. std::str query = "select * from table;"; But,
std::str query = "select * from table"; will work.

Creating Custom WMI classes for SCCM queries

I am working to create a custom WMI class for use with SCCM's device collection membership query rules to expose some organization specific information to SCCM for collection creation. I have managed to add a new class in with the MOF file below, and it shows up in the GUI as expected with the desired display name.
The only issue I believe I have left to solve is how to make the generated query work as expected. I know by default joins are not supported in WQL. However Microsoft seems to be using them regularly in these queries, and I have verified they work as expected outside of the application. Is there some sort of joining class I need to create to make this work? Is there some attribute to designate a property as a forigen key??
I have searched through the System Center Configuration Manager SDK documentation, and the WMI reference on the Windows Dev Center site for a few hours without much luck and would really appreciate any helpful input.
MOF File:
#pragma namespace ("\\\\.\\root\\sms\\site_lab")
[DisplayName("CMDB CI Computer")]
class SMS_G_System_MTS_cmdb_ci_computer : SMS_G_System
{
[key] uint32 ResourceID;
string asset_tag;
string dv_company;
string dv_cost_center;
string dv_location;
};
SCCM Generated Query:
select * from SMS_R_System inner join SMS_G_System_MTS_cmdb_ci_computer on SMS_G_System_MTS_cmdb_ci_computer.ResourceID = SMS_R_System.ResourceId
I am testing these commands with the Get-CimInstance command in powershell with the below results
Powershell:
This command returns the joined objects as expected.
Get-CimInstance -Namespace 'root\sms\site_lab' -Query 'select SMS_G_System_PROCESSOR.Architecture from SMS_R_System inner join SMS_G_System_PROCESSOR on SMS_G_System_PROCESSOR.ResourceId = SMS_R_System.ResourceId'
This command throws an "Invalid Query" Error.
Get-CimInstance -Namespace 'root\sms\site_lab' -Query 'select asset_tag from SMS_R_System inner join SMS_G_System_MTS_cmdb_ci_computer on SMS_G_System_MTS_cmdb_ci_computer.ResourceID = SMS_R_System.ResourceId'

MySQL C++ Connector: How do I get the thread/connection Id?

I'm trying to find out how to obtain the MySQL Connection/thread id using Connector C++.
mysql_thread_id(MYSQL* ) seems to be available for just this, but I'm not sure how to get an instance of MYSQL from the Connector C++.
What I've tried:
int threadId = mysql_thread_id(NULL);
But this just returns zero.
Any ideas?
The function mysql_thread_id() expects a pointer to a connection object created by the native MySQL C API's mysql_connect(...) function. Connector/C++ has buried that object very deep (I looked). The alternative suggested by MySQL's documentation here is to execute query SELECT CONNECTION_ID() and the returned result will be the ID you're looking for.

Addressing to temporary table created through CDatabase::ExecuteSQL

Consider following code and advise, why can I not address the temporary table created in the current session.
CDatabase cdb;
CString csConnectionString = "Dsn=prm2;Driver={INFORMIX 3.34 32 BIT};Host=10.XXX.XXX.XXX;Server=SRVNAME;Service=turbo;Protocol=olsoctcp;Database=DBNAME;Uid=user;Pwd=password";
cdb.OpenEx(csConnectionString, CDatabase::noOdbcDialog);
cdb.ExecuteSQL(CString("Set Isolation to Dirty Read"));
...
CString csStatement1 = "SELECT serno FROM TABLE1 into temp ttt_1;"
CString csStatement2 = "DROP TABLE ttt_1";
cdb.ExecuteSQL(csStatement1); // point1
cdb.ExecuteSQL(csStatement2); // point2
...
cdb.Close();
At point1 everything is fine. At point2 I have:
The specified table (ttt_1) is not in the database. State:S0002,Native:-206,Origin:[Informix][Informix ODBC Driver][Informix]
I tried to specify username as prefix (like user.ttt_1 or "user".ttt_1); I tried to create permanent table within respective statement in csStatement1 and every time it failed at point2. But when I tried to create same temporary table twice within csStatement1 I got the message that the temporary table already exists in session.
Please advise: what is wrong and how can I address created temporary tables.
it is all to do with ODBC autocommit mode. By default ODBC uses the option what is defined during the connection, and according to connectionstrings.com the default settings for Informix is commitretain=false.
You have two options: either set it via the connection string (commitretain=true) or (better option) via the ODBC. For a set of statements where you'd like to retain the temp table activate the manual commit mode via SqlSetConnectAttr, then execute a few statements and then call SqlEndTran. Please note, that in manual mode you do not need to call BEGIN TRANSACTION, as it will start automatically (behaviour similar to Oracle)
Please note that ODBC applications should not use Transact-SQL transaction statements such as BEGIN TRANSACTION, COMMIT TRANSACTION, or ROLLBACK TRANSACTION, but use the ODBC commands.

QODBC wrong value for numeric

I try to select numeric(20,0) values from a Microsoft SQLServer database.
Therefore I connect to an Microsoft SQL Server over ODBC. I use the SQLServer Native Client 10.0 driver.
The way I connect and select data in my QT-project is the following:
db = QSqlDatabase::addDatabase("QODBC", "DBConnection");
db.open();
query.exec("SELECT * FROM TABLE")
while (query.next()) {
//Do something with query.value(0)
}
The problem now is when I look what kind of QVariant is returned from query.value() I see that it is a double. But double values are only good for about 16 digits and not for 20. For example in the select the value should be 10903012224000000001 but I get 10903012224000000000.
Is there any way to tell QT which type of value it should return?
An exact string value would suffice.
The way query.value(0).toXXX doesn´t work because it seems to start the transformation with the double value.
On topic:
i´m sure that the problem is in QT. When I use the same ODBC-Driver in a Java aplication I get the right values back.
Hi I found a bugreport https://bugreports.qt-project.org/browse/QTBUG-10451
The solution is to set numericalPrecisionPolicy from LowPrecisionDouble to HighPrecision
the following codeline is to add and then the qVariant is qString and everything works fine
db.setNumericalPrecisionPolicy(QSql::HighPrecision);