How to bind a LIKE wildcard in SQLite3 - sql

I'd like to run the SQL query: SELECT COUNT(id) AS nbr FROM user WHERE name LIKE '%John%', and get the number of records matched by the keyword John.
So I've written the following code :
unsigned int nbr;
char *sql, *like;
sqlite3 *db;
sqlite3_stmt *stmt;
/* Database connection etc. */
like = _make_string("%%%s%%", keyword); /* keyword: John */
printf("Like clause: %s\n", like);
sql = _make_string("SELECT COUNT(id) AS nbr FROM user WHERE name LIKE ?");
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, like, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) != SQLITE_ROW) {
/* error, SQL execution failed */
}
nbr = sqlite3_column_int64(stmt, 1);
printf("Number of record: %u\n", nbr);
/* Free strings, finalize statement, disconnect db etc. */
For reason of simplicity, some return value tests are ignored in the snippet. _make_string(const char *fmt, ...) is a printf-like function which can form strings, and it did return %John% to me.
However, my code always returns 0 record. I have tried the SQL in sqlite3 command line shell, but it has found 2 records.
Any idea please ?
I've hard coded the LIKE clause and removed the sqlite3_bind_text function, and it doesn't change the result.
sql = _make_string("SELECT COUNT(id) AS nbr FROM client WHERE name LIKE '%John%'");
sqlite3_prepare_v2(db, sql, -1, &stmt, NULL);
if (sqlite3_step(stmt) != SQLITE_ROW) {
/* error */
}
nbr = sqlite3_column_int64(stmt, 1);
printf("Number of record: %u\n", nbr);
The program always returns 0 records.

Well, I've found the answer in the mailing list archive of SQLite Why bind indexes start from 1 and column indexes start from 0?
In fact, the bind index starts from 1, but the column index starts from 0. So the code should be modified as the following
nbr = sqlite3_column_int64(stmt, 0);
printf("Number of record: %u.\n", nbr);
Now the program returns 2 (records) !

Related

How to get the name of the last column from the SQL table without traversing in SQLite3?

My database contains 'n' number of columns.
For example:
Name city phone number ..............,
Exactly I don't know about the total number of columns and name of the last column.
The name of the columns will be changed at run time (such as The name of columns are not constant fields).
#include <stdio.h> /* needed for vsnprintf */
#include <stdlib.h> /* needed for malloc-free */
#include <string.h>
#include <sqlite3.h>
char * sql = PRAGMA table_info(table_name);
int i = 0;
rc = sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);
printf(" PRAGMA: rc = %d\n", rc);
if(rc != SQLITE_OK )
{
printf("Error: %s:Unable to Query the SQL Column from the table.\n", zErrMsg);
}
else if(rc == SQLITE_OK)
{
while(sqlite3_step(stmt) == SQLITE_ROW)
{
int totCol = sqlite3_column_count(stmt);
for(i=0; i<totCol ;i++)
{
printf("Column-Name: %s\n", sqlite3_column_text(stmt, i));
}
}
}
Through the above pragma command, I am traversing the entire columns in the SQL table and found the name of the last column.
Is there any way to know the name of the last column without traversing the entire columns in the SQL table.
Note: I don't want to do the following things
Executing more than one SQL statement.
Traversing the entire columns to find the last column from the SQL table.
I believe that you can achieve this using the following as the basis :-
SELECT name FROM pragma_table_info('table_name') ORDER BY cid DESC LIMIT 1;
As described in PRAGMA Statements - PRAGMA functions

Need an Oracle Pro*C program that queries for all of a user's tables

I'm new to Pro-C and Oracle (but not databases) so I probably need some fundamental help on what I'm doing wrong. I wrote the following Pro*C program to query for all the tables owned by a specific user:
#include <stdio.h>
EXEC SQL INCLUDE SQLCA;
int main() {
int i;
char oraCreds[10] = "user/pass";
char tables[50][50], parts[50][50];
exec sql connect :oraCreds;
if (sqlca.sqlcode != 0) {
printf("ERROR abbreviated\n");
return(0);
}
EXEC SQL SELECT TABLE_NAME
INTO :tables
FROM USER_TABLES;
if (sqlca.sqlcode != 0) {
printf("ERROR: Could not query database for user tables\n");
printf("\tError Code: %d\n", sqlca.sqlcode);
printf("\t%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
} else {
for (i = 0; i < 50; i++) {
printf("\nTable %d: %s\n", i+1, tables[i]);
}
}
// Code below inserted here
return(0);
}
This produces the following error:
ERROR: Could not query database for user tables
Error Code: 1403
ORA-01403: no data found
The problem is that there are records in user_tables and in sqlplus I can do a typical SELECT TABLE_NAME FROM USER_TABLES; in order to verify that.
In an attempt to verify some of the basic functionality of above program, I inserted the following query at the comment.
EXEC SQL SELECT NAME, PART_NO
INTO :tables, :parts
FROM ITEMS;
if (sqlca.sqlcode != 0) {
printf("ERROR: Could not query database for user tables\n");
printf("\tError Code: %d\n", sqlca.sqlcode);
printf("\t%.*s\n", sqlca.sqlerrm.sqlerrml, sqlca.sqlerrm.sqlerrmc);
} else {
for (i = 0; i < 50; i++) {
printf("\nTable %d: %s\n", i+1, tables[i]);
}
}
This second query gives the expected results and prints out one line for each item's name.
If I understand correctly, the table, user_tables, is a standard part of Oracle, so is there something special about it that would be throwing off my query? I've started reading some alternate ways to query for the user's tables, but I would love to know why the above method does not work.

SQLite3 - select query fails with Unicode characters?

My sqlite3 SELECT query fails if the query contains any Unicode characters. ie, the below query returns 0 instead of the actual count. I am generating the select query using C++/Visual Studio 2010.
SELECT COUNT() FROM mytable where path = "C:\\sølvgut.txt";
When I execute the above query using SQLite Expert editor it working as expected. But in my code I am using a wrapper class CppSQLite3.cpp to execute the query which is causing the issue. In the below code, it getting inside the code else if (nRet == SQLITE_ROW)
CppSQLite3Query CppSQLite3DB::execQuery(const char* szSQL)
{
checkDB();
sqlite3_stmt* pVM = compile(szSQL);
int nRet = sqlite3_step(pVM);
if (nRet == SQLITE_DONE)
{
// no rows
return CppSQLite3Query(mpDB, pVM, true/*eof*/);
}
else if (nRet == SQLITE_ROW)
{
// at least 1 row
return CppSQLite3Query(mpDB, pVM, false/*eof*/);
}
else
{
nRet = sqlite3_finalize(pVM);
const char* szError= sqlite3_errmsg(mpDB);
throw CppSQLite3Exception(nRet, (char*)szError, DONT_DELETE_MSG);
}
}

Delete column from Sqlite database

Basically I have to enter all textfield values in database then have to use for sending to webservice. So when the one column details send to service then have to delete that column.
I have done this:
-(void)deleteTableDataFromSavedDataTable:(NSString *)lastID {
NSString *sql_str=[NSString stringWithFormat:#"DELETE FROM FormInfoValues where Phone = %#",lastID];
const char *sql = [sql_str UTF8String];
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK)
{
NSLog(#"sql delete statement is ");
sqlite3_stmt *deleteStmt;
if(sqlite3_prepare_v2(database, sql, -1, &deleteStmt, NULL) == SQLITE_OK)
{
NSLog(#"sql delete statement is %#", deleteStmt);
if(sqlite3_step(deleteStmt) != SQLITE_DONE )
{
NSLog( #"Error: %s", sqlite3_errmsg(database) );
}
else
{
NSLog( #"row id = %lld", (sqlite3_last_insert_rowid(database)+1));
NSLog(#"No Error");
}
}
sqlite3_finalize(deleteStmt);
}
sqlite3_close(database);
}
but its not deleting after sending. Why its not calling?
give me ideas..
It's quite possible I'm not understanding your issue properly -- so I apologize in advance if so.
Regarding: "...then have to delete that column."
-- If you want to clear the data in a column (by setting it to zero, or empty string, or NULL) then you'll want to use the UPDATE command in SQL. The DELETE command always deletes ROWS.
-- If you really must remove a column from a table's schema, you'll have to create a new table in sqlite. (Sqlite allows you to ADD a column via ALTER TABLE command, and some other databases DO allow you to drop a column using ALTER TABLE as well.) You can quickly copy a table (without it's constraints, etc) via e.g.:
CREATE TABLE MyOutput as SELECT a,b,d,f,h,z from MyOriginal;
-- If your output is created by a SELECT statement, just avoid using "*" and specify just the columns you want included.

sqlite3 datetime not functioning properly on iPhone

I am having trouble getting sqlite3 to do comparisons between datetimes. On my mac, when I run the sql queries, it works. However, on the iPhone, the exact same query fails.
I have a sqlite3 table setup as follows:
CREATE TABLE IF NOT EXISTS `Artists` (
`id` int(11) NOT NULL PRIMARY KEY,
`name` varchar(256) NOT NULL,
`lastUpdate` date NOT NULL default CURRENT_TIMESTAMP ,
...
...
);
I can insert an artist with:
INSERT OR IGNORE INTO `Artists` (`id`,`name`) VALUES ('1','Justin');
I am trying to find the number of artists that have not been updated for the last 2 seconds (to keep it short):
SELECT COUNT(*) FROM `Artists` WHERE `id` = ? AND `lastUpdate` < datetime('now','-2 seconds');
On the iPhone, this returns 0. On my pc, it returns 1. I am expecting the value to be 1. What is the difference? I am retrieving the value by:
-(BOOL) artistNeedsUpdating:(int)artistId
{
[dbLock lock];
BOOL result = NO;
sqlite3_stmt *statement;
const char* query = "SELECT COUNT(*) FROM `Artists` WHERE `id` = ? AND `lastUpdate` < datetime('now','-2 seconds');";
if(sqlite3_prepare_v2(database, query, -1, &statement, NULL) == SQLITE_OK){
sqlite3_bind_int(statement, 1, artistId);
if(sqlite3_step(statement) == SQLITE_ROW){
if(sqlite3_column_int(statement, 0) > 0) // If 0, then we don't need to update
result = YES;
}
sqlite3_finalize(statement);
}
[dbLock unlock];
return result;
}
I am confused as to why it works on one platform but not the other, does anybody have any ideas?
Thank you,
Justin
Nevermind, it was my mistake.
I was updating the row after it got done with
UPDATE `Artists` SET `lastUpdate`='CURRENT_TIMESTAMP';
When it should have been:
UPDATE `Artists` SET `lastUpdate`=CURRENT_TIMESTAMP;