I'm using the following for a LIKE query. Is this technique for LIKE correct?
selectstmtSearch = nil;
if(selectstmtSearch == nil){
const char *sql = "SELECT col1, col2 FROM table1 t1 JOIN table2 t2 ON t1.cityid = t2.cityid where t1.cityname like ?001 order by t1.cityname";
if(sqlite3_prepare_v2(databaseSearch, sql, -1, &selectstmtSearch, NULL) == SQLITE_OK)
{
sqlite3_bind_text(selectstmtSearch, 1, [[NSString stringWithFormat:#"%%%#%%", searchText] UTF8String], -1, SQLITE_TRANSIENT);
}
}
The problem I'm having is after a few uses of this, I get an error 14 on sqlite3_open(), which is unable to open database. If I replace the LIKE with something such as:
SELECT col1, col2
FROM table1 t1
JOIN table2 t2 ON t1.cityid = t2.cityid
where t1.cityname = ?
order by t1.cityname
It works fine. I do open/close the DB before after the above code. Is there a way to troubleshoot exactly why the database can't be opened and what its relationship to my LIKE syntax is?
You must sqlite3_reset or sqlite3_finalize(selectstmtSearch) before you close the database connection.
Related
I want to rewrite the following query using jooq:
with first_temp as (
select a.id as lie_id
from first_table a
where a.some_Field = 100160
), second_temp as (
select b.id as ben_id
from second_table b
where b.email = 'some.email#gmail.com'
) insert into third_table (first_table_id, second_table_id)
select a.lie_id, b.ben_id from first_temp a, second_temp b;
I was trying something like the following:
DriverManager.getConnection(url, login, password).use {
val create = DSL.using(it, SQLDialect.POSTGRES)
create.with("first_temp").`as`(create.select(FIRST_TABLE.ID.`as`("lie_id")))
.with("second_temp").`as`(create.select(SECOND_TABLE.ID.`as`("ben_id")))
.insertInto(THIRD_TABLE, THIRD_TABLE.FIRST_TABLE_ID, THIRD_TABLE.SECOND_TABLE_ID)
.select(create.select().from("first_temp", "second_temp"), create.select().from("second_temp")))
}
But without success.
Your fixed query
// You forgot FROM and WHERE clauses in your CTEs!
create.with("first_temp").`as`(
create.select(FIRST_TABLE.ID.`as`("lie_id"))
.from(FIRST_TABLE)
.where(FIRST_TABLE.SOME_FIELD.eq(100160)))
.with("second_temp").`as`(
create.select(SECOND_TABLE.ID.`as`("ben_id"))
.from(SECOND_TABLE)
.where(SECOND_TABLE.EMAIL.eq("some.email#gmail.com")))
.insertInto(THIRD_TABLE, THIRD_TABLE.FIRST_TABLE_ID, THIRD_TABLE.SECOND_TABLE_ID)
// You had too many queries in this part of the statement, and
// didn't project the two columns you were interested int
.select(create.select(
field(name("first_temp", "lie_id")),
field(name("second_temp", "ben_id")))
.from("first_temp", "second_temp"))
// Don't forget this ;-)
.execute();
But frankly, why even use CTE at all? Your query would be much simpler like this, both in SQL and in jOOQ (assuming that you really want this cartesian product):
Better SQL Version
insert into third_table (first_table_id, second_table_id)
select a.id, b.id
from first_table a, second_table b
where a.some_field = 100160
and b.email = 'some.email#gmail.com';
Better jOOQ Version
create.insertInto(THIRD_TABLE, THIRD_TABLE.FIRST_TABLE_ID, THIRD_TABLE.SECOND_TABLE_ID)
.select(create.select(FIRST_TABLE.ID, SECOND_TABLE.ID)
.from(FIRST_TABLE, SECOND_TABLE)
.where(FIRST_TABLE.SOME_FIELD.eq(100160))
.and(SECOND_TABLE.EMAIL.eq("some_email#gmail.com")))
.execute();
I have IPhone application in which I am inserting data. It works fine when I fetch all the data without any condition then it works fine if given any condition like
following query then it does not show anything.
NSString *select =
[NSString stringWithFormat:
#"SELECT * from ContentMaster As ml
LEFT JOIN ContentTagging As cat
ON cat.ContentID = ml.ContentID
where cat.ContenTagText= \'%#\'" ,appDelegate.tagInput];
const char *sql = [select UTF8String];
then it does not show any thing using this if i use the select * form ContentMaster then it shows all records added.
Try this.
SELECT * from ContentMaster
LEFT JOIN ContentTagging
ON ContentMaster.ContentID = ContentTagging.ContentID
WHERE ContentTagging.ContenTagText= \'%#\'"
Please can anyone tell me why we write NULL in the fifth parameter below?
if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK)
Thanks in advance.
As long as your sql has only one statement, you don't need to use the fifth parameter. When sql has more than one statement, you can receive a pointer to the beginning of the next statement.
For example:
const char* sql =
"DROP TABLE price_list;"
"CREATE TABLE price_list ( item TEXT, price INTEGER)";
while ( *sql ) {
sqlite3_stmt* statement;
sqlite3_prepare_v2(db, sql, -1, &statement, &sql);
sqlite_step(statement);
sqlite_finalize(statement);
}
Because you don't care about the uncompiled part of the SQL statement. From the docs:
If pzTail is not NULL then *pzTail is made to point to the first byte past the end of the first SQL statement in zSql. These routines only compile the first statement in zSql, so *pzTail is left pointing to what remains uncompiled.
It's useful to have this if you have a string with many SQL statements, but if you don't then it's just cruft.
This question already has answers here:
SQlite: select into?
(5 answers)
Closed 8 years ago.
Right now my statement looks like this:
NSString *sqlJoin = #"SELECT * INTO #tmp FROM foods JOIN bridgeTable ON foods.foodID = bridgeTable.foodID";
if(sqlite3_prepare_v2(database, [sqlJoin UTF8String],
-1, &statement, nil) == SQLITE_OK) {
while (sqlite3_step(statement) == SQLITE_ROW) {
}
sqlite3_finalize(statement);
}
else {
NSLog(#"Statement: %s", sqlite3_errmsg(database));
}
NSLog(#"count: %i", [foodArray count]);
The output I'm getting is:
2012-07-06 10:32:04.940 ProFitness[7087:f803] Statement: near "INTO": syntax error
2012-07-06 10:32:04.940 ProFitness[7087:f803] count: 0
2012-07-06 10:32:04.940 ProFitness[7087:f803] sql statement: SELECT * FROM #tmp WHERE TableID = '3'
2012-07-06 10:32:04.941 ProFitness[7087:f803] Statement: near "#tmp": syntax error
If my syntax is wrong, what SHOULD it look like?
You have to create the temporary temp yourself using:
CREATE TEMP TABLE xxxx
then you would use
SELECT * INTO xxxx
For more information see SQLite's Use Of Temporary Disk Files.
I'm trying to use the SQLite C API in my iPhone app. I'm trying to query an SQLite database for the number of records that have been completed after a certain date. The database saves the completed date as text in YYYY-MM-dd format. For example the text 2009-04-10 might appear as a completed date.
When I query the database from the commandline my query works, but when run from the app, it doesn't. Here's what I'm doing:
From the commandline, I run this query:
sqlite> SELECT COUNT(*) FROM tasks WHERE completed > '2009-04-09'
...> go
1
As you can see, there is one record found as I expect.
In my app, I execute this code (written in Objective-C, obviously):
static sqlite3_stmt *count_tasks_statement = nil;
if(count_tasks_statement == nil) {
const char *sql = "SELECT COUNT(*) FROM tasks WHERE completed > '?'";
if (sqlite3_prepare_v2(database, sql, -1, &count_tasks_statement, NULL) != SQLITE_OK) {
NSAssert1(0, #"Error: failed to prepare statement with message '%s'.", sqlite3_errmsg(database));
}
}
NSString *today = #"2009-04-09";
sqlite3_bind_text(count_tasks_statement, 1, [today UTF8String], -1, SQLITE_TRANSIENT);
// Get the row count from the query
NSInteger taskCount = 0;
if(sqlite3_step(count_tasks_statement) == SQLITE_ROW) {
// The second parameter indicates the column index into the result set.
taskCount = sqlite3_column_int(count_tasks_statement, 0);
}
// Reset the statement for future reuse.
sqlite3_reset(count_tasks_statement);
When I use the debugger on this code, and examine the taskCount variable, it is set to 0, indicating that no records were found. (If I change the code to return primary keys for found rows, it still returns nothing.)
Since it works from the commandline, but doesn't in my code, I assume that I'm doing something wrong with either the quoting of the question mark in my SQL, or with the binding of the literal text date to the query. But, I've tried it lots of different ways with no luck. Help!
Don't put parameter placeholders inside quotes, even if the value is a string or date literal.
const char *sql = "SELECT COUNT(*) FROM tasks WHERE completed > ?";
I think that you do not need the extra quotes around the question mark.
Try
const char *sql = "SELECT COUNT(*) FROM tasks WHERE completed > ?";
and it should work.