My sqlite insert statement is as
char *testSQL;
testSQL = "INSERT INTO Test (id, tx_time) VALUES ("+id+ ", datetime("+timestamp+",'unixepoch', 'localtime'));";
I'm trying to convert above into prepared statement using sqlite3_bind.
testSQL = "INSERT INTO Test (id, tx_time) VALUES (?, ?);";
I can bind id simply using sqlite3_bind_int(stmt, 1, id) but how can I bind datetime function?
Put the datetime in the SQL instead:
char *testSQL;
testSQL = "INSERT INTO Test (id, tx_time) "
"VALUES (?, datetime(?,'unixepoch', 'localtime'));"
And use sqlite3_bind_int to bind timestamp instead.
Related
I want to create a SQL table in QT C++. So I have made this code.
And it is going to create a database for me, where the first argument tableName is the name of the table I want to create. Then the next argument is quite tricky.
Here, columns, specify the column name and it's data type. I think this is a bad way to do. Example
QVector<QPair<QString, QString>> myColumns = new QVector<QPair<QString, QString>>{{"ID", "BIGINT"}, {"logging_id", "INT"}};
Because If i have for example like 50 columns. The myColumns is going to be very long.
My question if QT C++ have some kind of reflections, so I can:
Get the name if every field
Get the data type of every field
If the field is an array, then I'm going to know how many elements there are inside that array
I was planning to have an entity class where I create a class, and use that class to get the information to create each columns in the database.
void Database::createTable(QString tableName, const QVector<QPair<QString, QString>> columns){
QSqlQuery query;
for (int i = 0; i < columns.length(); i++){
/* Get the Qpair values */
QString columnName = columns.at(i).first;
QString dataType = columns.at(i).second;
/* If key is ID, then try to create a new table */
if(columnName == "ID"){
query.exec("CREATE TABLE " + tableName + "(" + columnName + " " + dataType + " NOT NULL AUTO_INCREMENT PRIMARY KEY)");
continue;
}
/* If not, then try append new columns */
query.exec("ALTER TABLE " + tableName + " ADD " + columnName + " " + dataType);
}
}
below is part of my code,
...
char hashvalue[]="somehash"; // or i can use std::string
SQLCHAR* query = (SQLCHAR*)"SELECT username FROM users WHERE hash = ..." ;
SQLExecDirectA( hStmt, query, SQL_NTS );
...
In the code above I have no idea how to insert into query hashvalue to execute my query like this:
SQLCHAR* query = (SQLCHAR*)"SELECT username FROM users WHERE hash = "somehash"" ;
I 'm very new to sql, thanks in advance for help.
Use std::string
std::string query_string = "SELECT username FROM users WHERE hash = ";
query_string += hashvalue;
SQLExecDirectA(hStmt, query_string.c_str(), SQL_NTS);
Another method:
char query_buffer[1024];
snprintf(query_buffer,
"SELECT username FROM users WHERE hash = %s",
hashValue);
SQLExecDirectA(hStmt, query_buffer, SQL_NTS);
Basically, your question is how to create a formatted string and has nothing to do with SQL.
I'm using pqlib with postgresql version 9.1.11
I have the following code
const char *spid = std::to_string(pid).c_str();
PGresult *res;
const char *paramValues[2] = {u->getID().c_str(), spid};
std::string table;
table = table.append("public.\"").append(Constants::USER_PATTERNS_TABLE).append("\"");
std::string param_name_pid = Constants::RELATION_TABLE_PATTERN_ID;
std::string param_name_uid = Constants::RELATION_TABLE_USER_ID;
std::string command = Constants::INSERT_COMMAND + table + " (" + param_name_uid + ", " + param_name_pid + ") VALUES ($1, $2::int)";
std::cout << "command: " << command << std::endl;
res = PQexecParams(conn, command.c_str(), 2, NULL, paramValues, NULL, NULL,0);
Where
INSERT_COMMAND = "INSERT INTO " (string)
USER_PATTERN_TABLE = "User_Patterns" (string)
RELATION_TABLE_PATTERN_ID = "pattern_id" (string)
RELATION_TABLE_USER_ID = "user_id" (string)
pid = an int
u->getID() = a string
conn = the connection to the db
The table "User_Patterns" is defined as
CREATE TABLE "User_Patterns"(
user_id TEXT references public."User" (id) ON UPDATE CASCADE ON DELETE CASCADE
,pattern_id BIGSERIAL references public."Pattern" (id) ON UPDATE CASCADE
,CONSTRAINT user_patterns_pkey PRIMARY KEY (user_id,pattern_id) -- explicit pk
)WITH (
OIDS=FALSE
);
I already have a user and a pattern loaded into their respective tables.
The command generated is :
INSERT INTO public."User_Patterns" (user_id, pattern_id) VALUES ($1, $2::int)
I also tried with $2, $2::bigint, $2::int4
The problem is:
I receive the error :
ERROR: invalid input syntax for integer: "public.""
I already use PQexecParams to store users and patterns, the only difference is that they all have text/xml fields (the only int field on patterns is a serial one and I don't store that value myself) but because the user_patterns is a relation table I need to store and int for the pattern_id.
I already read the docs for pqlib and saw the examples, both are useless.
The problem is in the lines:
const char *spid = std::to_string(pid).c_str();
const char *paramValues[2] = {u->getID().c_str(), spid};
std::to_string(pid) creates temporary string and .c_str() returns a pointer to an internal representation of this string, which is destroyed at the end of the line, resulting in a dead pointer. You may also see answer to the question
stringstream::str copy lifetime
I must develop a social network simulator using C++ and QT library.
I store user into mysql database using QODBC.
When i run my application, i throw a SIGSEGV error.
here, my function which throw this error :
QMutex userMutex;
userMutex.lock();
QListIterator<User*> i(users);
User* user;
QString sql = "insert into t_user (id, pseudo, name, firstname, birthdate) values ";
QString bindValue = QString::fromStdString("(?, ?, ?, ?, ?),").repeated(users.count());
sql.append(bindValue);
QSqlQuery query = QSqlQuery(Interface::getCnx());
query.prepare(sql);
while(i.hasNext())
{
user = i.next();
query.addBindValue(QString::number(user->getId()));
query.addBindValue(user->getPseudo());
query.addBindValue(user->getName());
query.addBindValue(user->getFirstname());
QString birthdate = QString::number(user->getBirthDate().year()) + "-" + QString::number(user->getBirthDate().month()) + "-" + QString::number(user->getBirthDate().day());
query.addBindValue(birthdate);
}
query.exec();
userMutex.unlock();
It is "query.exec()" line which throw this error.
Do you see what's wrong?
First of all you have an extra comma here:
QString bindValue = QString::fromStdString("(?, ?, ?, ?, ?),").repeated(users.count());
So or you "repeat" string count-1 times and then add "(?, ?, ?, ?, ?)":
QString bindValue = QString::fromStdString("(?, ?, ?, ?, ?),").repeated(users.count() - 1);
bindValue "(?, ?, ?, ?, ?)";
Or you have to remove last char of your string bindValue.
I found the answer ... i guess.
This SIGSEGV error has disappeared when i decrease the size of the list.
Before the list contains 1000 users but now it constains only 800 users per call to this méthod.
Thanks for your help.
I was trying to insert into a table some data, but I wasn't sure what flag allows me to return the primary key. I believe I recall MSSQL using RETURNING, and some others tack on RETURNS at the end.
could someone help out with the appending of it?
I'm trying to return TABLEA.a, and my query and design would look something like this:
sqlite3 *db;
sqlite3_open("...",&db);
std::string query;
query = "insert into TABLEA (b,c,d,e) values (#b,\"#c\",#d,#e);";
//^--this needs to be modified.
sqlite3_stmt *sqlstmt;
int rc;
rc = sqlite3_prepare_v2(db, query.c_str(), 01, &sqlstmt, 0);
sqlite3_step(sqlstmt);
int ID;
ID = sqlite3_column_integer(sqlstmt,0);
Have you tried sqlite3_last_insert_rowid ?