I have a two tables in SQLITE and View where I try to compine these two tables (my idea is to get all the rows from table1 where table1.field1 and table2.field99 have the same value.
Tables and View are Table1,Table2 and View1
View code is "SELECT * FROM Table1 JOIN Table2 ON UPPER(Field1) LIKE UPPER(Table2.Field99)"
If I run
SELECT * FROM View1;
or if I run
SELECT * FROM Table1 JOIN Table2 ON UPPER(Field1) LIKE UPPER(Field99);
from sqlite shell it returns the rows just fine.
But if i try to run those SQL statements in C++ with this code:
if(sqlite3_prepare_v2(database,SQLStr,-1,&stmt,0)==SQLITE_OK){
int cols = sqlite3_column_count(stmt);
printf("Query OK: %s \nColumns: %i\n", SQLStr, cols);
while(1) {
status = sqlite3_step(stmt);
if(status == SQLITE_ROW) {
printf("This is a row!\n");
} else if(status == SQLITE_DONE) {
printf("Rows handled!\n");
break;
} else {
printf("Other status!\n");
break;
}
}
}
It just returns:
Rows handled: SELECT * FROM View1;
Columns: 7
Rows handled!
But it doesn't return any rows like the shell does. (there should be "This is a row!" printed for every row in query. I tried to add table names to queries but no help. I also tried to run for example SELECT * FROM Table1; and then the C++ returns the rows. Is it so that SQLITE in C++ can't handle JOINS or Views?
if u want to collect the rows then use Sqlite3_exec() API or column API.sqlite3_step() only evaluates the prepared statement it does not fetch the results, for that u have to use different api available or u can use sqlite3_exec which is a wrapper.
check the following link
http://www.sqlite.org/c3ref/funclist.html
http://www.sqlite.org/cintro.html
All the best.
Related
I use sqlite on a c++ project, but I have a problem when i use WHERE on a column with TEXT values
I created a sqlite database:
CREATE TABLE User( id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(24))
When i try to get the value of the column with VARCHAR values, it doesn't work, and return me a STATUS_CODE 101 just after the sqlite3_step :
int res = 0;
sqlite3_stmt *request;
char *sqlSelection = (char *)"SELECT * FROM User WHERE name='bob' ";
int id = 0;
res = sqlite3_prepare_v2(db, sqlSelection, strlen(sqlSelection), &request, NULL);
if (!res){
while (res == SQLITE_OK || res == SQLITE_ROW){
res = sqlite3_step(request);
if (res == SQLITE_OK || res == SQLITE_ROW ){
id = sqlite3_column_int(request, 0);
printf("User exist %i \n",id);
}
}
sqlite3_finalize(request);
I also tried with LIKE but it also doesn't work
SELECT * FROM User WHERE name LIKE '%bob%'
But when I execute the same code but for an INTERGER value
SELECT * FROM User WHERE id=1
It work fine.
In DB Browser for SQLite all requests work fine.
To solve the problem I searched what status code 101 means.
Here is what they said.
(101) SQLITE_DONE
The SQLITE_DONE result code indicates that an operation has completed.
The SQLITE_DONE result code is most commonly seen as a return value
from sqlite3_step() indicating that the SQL statement has run to
completion. But SQLITE_DONE can also be returned by other multi-step
interfaces such as sqlite3_backup_step().
https://sqlite.org/rescode.html
So, you're getting 101 because there is no more result from SELECT SQL.
The solution was to replace the VARCHAR fields by TEXT.
SQLite for c++ seems to don't manage VARCHAR fields when they are used after the WHERE
For example my inquiry(question?) in SQL is:
SELECT * from COMPANY where imie="John",surname="Wattson",age=31;
I use sqlite3_exec where one of the arguments is callback. I don't know if this record is in my table, and would like to know it using sqlite_exec.
What should I do?
Sorry for my English. :(
If you just want to see if a record exists in the table, then you could do it with sqlite3_exec() using a callback function like this:
int myCallback(void *pUser, int argc, char **colData, char **colNames) {
int *flag = (int*)pUser;
*flag = 1;
return 1;
}
This works because if there are no records matching the query, then the callback function is not called. By returning 1 instead of 0, we are telling SQLite that we don't want any more rows from the query results.
Then, in the function where you are making the db query:
std::string sql = "SELECT * FROM COMPANY WHERE imie='John' AND surname='Wattson' AND age=31;";
char *pSql = sql.c_str(); // char*'s are better for talking to SQLite, and prior to C++14,
// a std::string is not guaranteed to be sequential in memory,
// so 'sql[0]' may not work right
char *pError = NULL;
int fHasResult = 0;
// db is an already-opened sqlite3*
int result = sqlite3_exec(db, pSql, myCallback, &fHasResult, &pError);
if (result) {
cout<<"Error was: "<<pError;
free(pError);
}
if (fHasResult) {
cout<<"The row exists in the database.";
}
else {
cout<<"The row does not exist in the database.";
}
You could use EXISTS, your query should then look something like this;
SELECT EXISTS (SELECT * FROM COMPANY WHERE imie="John" AND surname="Wattson" AND age=31);
For another example you could take a look at this;
Valid query to check if row exists in SQLite3
I am using the below code to get the number of columns in an oracle table.
char selectQuery[30000] = {'\0'};
strcpy(selectQuery, "SELECT COUNT(*) FROM USER_TAB_COLUMNS WHERE TABLE_NAME=\'");
strcat(selectQuery, tableName);
strcat(selectQuery, "\'");
strcpy((char*) stmt.arr, selectQuery);
stmt.len = strlen((char*) stmt.arr );
stmt.arr[stmt.len]= '\0';
EXEC SQL WHENEVER SQLERROR CONTINUE;
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL DECLARE SELECTCOLNU STATEMENT;
EXEC SQL PREPARE SELECTCOLNU FROM :stmt;
if(sqlca.sqlcode != 0)
{
DEBUG_LOG("SQL-ERR:Preparation of SELECT Query to get number of columns failed: Ora-Err: %d %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
return PREPARATION_FAILURE;
}
EXEC SQL EXECUTE SELECTCOLNU INTO:columnsNo;
if(sqlca.sqlcode < 0)
{
DEBUG_LOG("SQL-ERR:Execute failed: Ora-Err: %d %s\n", sqlca.sqlcode, sqlca.sqlerrm.sqlerrmc);
return EXECTUION_FAILURE;
}
DEBUG_LOG("Number of columns: %d\n", columnsNo);
When I execute the code, It doesn't give any error but I am getting "Number of columns: 0" as the output.
There are few columns in the table I am referring.
Am I doing anything wrong here?
Below is the declaration section...
EXEC SQL BEGIN DECLARE SECTION;
int columnsNo;
VARCHAR stmt[MAX_SQL];
EXEC SQL END DECLARE SECTION;
Don't "escape" the ' in a C- string. It will have \' just in the string, and that is not what you want because the ' is the database string quote, which you now escape for the database and the database doesn't understand the query now.
sprintf(selectQuery, "SELECT COUNT(*) FROM USER_TAB_COLUMNS WHERE TABLE_NAME='%s'", tableName);
Note:
stmt.len = strlen((char*) stmt.arr );
stmt.arr[stmt.len]= '\0';
In the above strlen counts the number of characters until a null character. Thus stmt.arr[stmt.len] is already null. (No harm, though.)
Can we execute Prepared statement(parametrised query) inside pqxx::pipeline,
we can insert plain sql statement like:
SELECT * FROM table
but can we do something like given below
pqxx::connection c;
c.prepare("SELECT_QUERY", "SELECT * FROM table");
pqxx::work w(c);
pqxx::pipeline p(w);
w.insert("SELECT_QUERY");
w.complete()
Thanks
in my table i have 3 column
id, somevalue (float), current timestamp
code below searches for the latest value in today's date and subtracts that with the value on monday of the same week. but i dont have any value stored for monday in this week so its NULL at the moment. but result of below code should be some value not null ???? dont understand how is it possible. pls explain.
select(SELECT power FROM newdb.newmeter
where date(dt)=curdate() order by dt desc limit 1)-
(select Power from newdb.newmeter
where date(dt)=(select date(subdate(now(), interval weekday(now()) day))));
as i was reading the similar questions-answers it looks like anything you do with null in mysql is null is it true??
if yes how do i resolve this
update:
i tried this but didnt work
select sum(amount) - coalesce(sum(due),0)
just wanted to add something more to this
i'm calling querydb as following for the mysql in c++
bool Querydb(char *query, double Myarray[1024])
{
//snip//
if (mysql_query(conn, query)) {
fprintf(stderr, "%s\n", mysql_error(conn));
return 0;
}
else {
res = mysql_use_result(conn);
//output table name
//printf("MySQL Tables in mysql database:\n");
//checking for null value in database
while((row = mysql_fetch_row(res))==NULL){
printf("ERROR_____NULL VALUE IN DATABASE ");
return 0;
}
//if not null then ...
while ((row = mysql_fetch_row(res)) != NULL){
printf("rows fetched %s\n", row[0]);
sprintf(buffer,"%s",row[0]);
value1 = atof(buffer);
Myarray[i]=value1;
//printf("Myarray in sql for daybutton = %f\n",Myarray[i]);
i++;
}
i=0;
//for(i=0;i<5;i++){
// printf("mya arr in sqlfunction = %f\n",Myarray[i]);}
return 1;
}
printf("if here then....where??\n");
//close connection
// mysql_free_result(res);
//return 0;
}
the above function works ok with different query when database has null but doesnt work with this query
select(SELECT power FROM newdb.newmeter
where date(dt)=curdate() order by dt desc limit 1)-
(select Power from newdb.newmeter
where date(dt)=(select date(subdate(now(), interval weekday(now()) day))));
it returns 1 even thought the answer is NULL...
Consult the manual on working with NULL values. They are treated specially http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html
What value would you want it to be? This isn't particularly specific to MySQL - operations involving null operands (including comparisons) have null results in most SQL dialects.
You may want to use COALESCE() to provide a "default" value which is used when your real target value is null.
work Around would be
select(SELECT power FROM newdb.newmeter
where date(dt)=curdate() order by dt desc limit 1)-
(select COALESCE(Power,0) from newdb.newmeter
where date(dt)=(select date(subdate(now(), interval weekday(now()) day))));