SQLite and Objective C - WHERE LIKE Statement Error - ios

I am trying to write a query that involves a WHERE LIKE statement, however I'm running into the following issue....
When I write the query like:
"SELECT * FROM db WHERE name LIKE \"%%#%%\""
It gets interpreted as:
SELECT * FROM db WHERE name LIKE "(null)"
When I query the following:
"SELECT * FROM db WHERE name LIKE \"%%%#%%\""
It gets interpreted as:
SELECT * FROM db WHERE name LIKE "0x0p+0pple"
This:
[#"SELECT * FROM db WHERE name LIKE \"%" stringByAppendingString:name] stringByAppendingString:#"%\""]
Is interpreted as:
SELECT * FROM db WHERE name LIKE "0x0p+0pple"
Is there a way to correct or work around this?

If you want to use a string format, it needs to be:
NSString *query = [NSString stringWithFormat:#"SELECT * FROM db WHERE name LIKE '%%%#%%'", someValue];
The first two %% become a single %. The %# gets replaced with whatever string is in someValue. And the final two %% become a single %.
query ends up being:
SELECT * FROM db WHERE db LIKE '%apple%'
assuming someValue is the string #"apple".
On a side note, it's best to avoid using SELECT * FROM if you are using the various sqlite3_column_xxx functions and specific index numbers because you can't be sure the order of the returned columns matches your code. It's safer and clearer to explicitly list the columns you want from the query.

Doi!
This:
[#"SELECT * FROM db WHERE name LIKE \"%%" stringByAppendingString:name] stringByAppendingString:#"%%\""]
Is interpreted as:
SELECT * FROM db WHERE db LIKE "%apple%"
Which is ACTUALLY what I'm looking for (hadn't realize that at first), this work around just feels a bit... unnecessarily lengthy.

Try this one.Its gonna work.
NSString *yourSqlQuery = [NSString stringWithFormat:#"Select * from yourTableName where name LIKE '%%%#%%'",name];

Related

JSQL Parser - info on dblink

I m using JSQLPARSER for the first time and I wonder if it s possible to detect remote links (oracle dblink)?
If for example a simple select * from table1#remote
For JSqlParser this would be no special identifier. However, it will accept it as a normal table name. You could extract all used table names using something like:
String sql = "select * from table1#remote";
Statement stmt = CCJSqlParserUtil.parse(sql);
TablesNamesFinder tablesNamesFinder = new TablesNamesFinder();
List<String> tableList = tablesNamesFinder.getTableList(stmt);
assertEquals(1, tableList.size());
assertTrue(tableList.contains("table1#remote"));
And after that, you have to check, like I did with junits assertions, if a table name matches remote dblink syntax.

Rails NOT IN query and regexp

I have array of strings:
a = ['*#foo.com', '*#bar.com', '*#baz.com']
I would like to query my model so I will get all the records where email isn't in any of above domains.
I could do:
Model.where.not(email: a)
If the list would be a list of strings but the list is more of a regexp.
It depends on your database adapter. You will probably be able to use raw SQL to write this type of query. For example in postgres you could do:
Model.where("email NOT SIMILAR TO '%#foo.com'")
I'm not saying thats exactly how you should be doing it but it's worth looking up your database's query language and see if anything matches your needs.
In your example you would have to join together your matchers as a single string and interpolate it into the query.
a = ['%#foo.com', '%#bar.com', '%#baz.com']
Model.where("email NOT SIMILAR TO ?", a.join("|"))
Use this code:
a = ['%#foo.com', '%#bar.com', '%#baz.com']
Model.where.not("email like ?",a.join("|"))
Replace * to % in array.

Batch insert values to a specific column in sqlite3 on iOS

I have a table in my database. I want to add values to a specific column in the table. Since there are like thousands plus rows in my table i figured i have to use batch update. The code is this but i get syntax error and a message saying there is no such row:
NSString *addProductColQuery = #"ALTER TABLE Sale ADD COLUMN Product text";
[self.dbManager loadDataFromDB:addProductColQuery];
NSString *batchstart = #"BEGIN IMMEDIATE TRANSACTION";
[self.dbManager loadDataFromDB:batchstart];
for (int i = 0; i<self.productInfo.count; i++)
{
NSString *addValue = [NSString stringWithFormat:#"INSERT INTO Sale (Product) VALUES (%#)",[tempProductArray objectAtIndex:i]];
[self.dbManager loadDataFromDB:addValue];
}
NSString *batchComit = #"COMMIT TRANSACTION";
[self.dbManager loadDataFromDB:batchComit];
Update:
I have managed to get the above code to work but now i am getting 90% CPU Usage on iphone6! I actually saw this coming since im using a for loop which is dead wrong to loop a query. Is there a way to batch insert the values to the rows in a specific column?
Are the values in tempProductArray text values? If so, you have to quote them in your SQL:
NSString *addValue = [NSString stringWithFormat:#"INSERT INTO Sale (Product) VALUES ('%#')", tempProductArray[i]];
Having shown you a quick solution, that's actually the wrong way to do it. It is inadvisable to use stringWithFormat to build SQL with text values. If any of those strings themselves have apostrophe characters in them, the SQL will fail. Also, if any of this data was provided by the end-user or from the network, you're exposed to SQL injection attacks.
The correct solution is to use sqlite3_prepare_v2 of the SQL without quotes, but with ? placeholder:
NSString *addValue = #"INSERT INTO Sale (Product) VALUES (?)";
And then, before calling sqlite3_step, you would call sqlite3_bind_text to bind a text value to the ? placeholder.
If your dbManager doesn't offer that capability, you'll have to add it. Or use a library, like FMDB, that offers this capability out of the box.

select records having string with single quote -informix

Hey I want to select records with name O'Neil, How can i do that in Informix.
select * from name_table where lastname = 'O'Neil' --> Doesn't Work.
You must escape single quote with another single quote:
select * from name_table where lastname = 'O''Neil';
With Informix, you generally have two choices.
The Standard SQL technique (described by Michal Niklas) always works and is the simple, recommended solution. All appearances of a single quote in a string are doubled up:
SELECT * FROM Name_Table WHERE LastName = 'O'Neill';
An alternative technique that works unless you have set DELIMIDENT in your environment is to use double quotes around the string:
SELECT * FROM Name_Table WHERE LastName = "O'Neill";
If delimited identifiers are enabled by DELIMIDENT, then this has a different meaning; the DBMS will be looking for a column called "O'Neill" in the table (because it is an identifier, not a string).
If you have both quotes in a string, then you have to be be careful:
SELECT * FROM QuoteTable WHERE Quote = 'He said, "Don''t"!';
SELECT * FROM QuoteTable WHERE Quote = "He said, ""Don't""!';
My 2nd answer with proposition of technology change.
I don't know what technology you use, but maybe you can use PreparedStatements. Example in Jython (Python that can use JDBC drivers):
db = DriverManager.getConnection(jdbc_url, usr, passwd)
pstm = db.prepareStatement("select * from name_table where lastname=?")
pstm.setString(1, "O'Neil")
rs = pstm.executeQuery()
while (rs.next()):
print('[%s]' % (rs.getString(1)))
As you see PreparedStatement use ? as a placeholder and then you must fill it using setString() method. It is very useful if you have to do many similar selects, inserts etc. Have a look at Java6 documentation for this: http://docs.oracle.com/javase/6/docs/api/java/sql/PreparedStatement.html
Similar techniques can be user for ODBC or other technologies.

Symfony, propel, question mark

I want to create a search function on my website, and I don't want to use a plugin for this thing, because it's very simple, but I can't solve this problem:
I give the keyword to the model which creates a query, but I couldn't figure out how to put joker characters in this query.
I'm using Propel
Dennis
The filterByXXX() query functions will use LIKE when your query contains wildcards:
$books = BookQuery::create()
->filterByTitle('War%')
->find();
// example Query generated for a MySQL database
$query = 'SELECT book.* from `book` WHERE book.TITLE LIKE :p1'; // :p1 => 'War%'
Remember, the wildcards you can use in SQL are _ for exactly one and % for zero or more characters. So not ? or *.

Resources