I'm trying to insert a special character values into my sqlite table. For that i have used following query, that contains octal values.
"INSERT INTO \"manufacturers\" VALUES(NULL,NULL,NULL,'1970-01-01 00:00:00','1970-01-01 00:00:00','35','A Priorite\\047');"
when i displaying the names it doesn't converted to corresponding string value, it displays the same octal value inserted as (A Priorite\047);
Now i need an suggestion to convert the octal value to string or char by using sqlite statements.
I know we can easily obtain it by using java code but my requirement is to do it by use of sqlite statements. Here the last value is the name field which is contains the octal value of \047(as string ').
I've also tried to convert the decimal value to char, it works fine. In my case, if i convert the octal value to decimal value then i can easily convert to char. but i can't convert octal to decimal.
Note: I'm having thousands of record, so can't manually insert the special characters into each row of table. And I'm not supposed to insert the values manually.
Thanks in Advance. Any help would be appreciated.
SQLite does not have octal escapes.
In Android, you should just use parameters to insert strings:
String sillyDate = "1970-01-01 00:00:00";
String someNumberAsString = "35";
String name = "A Priorite\047";
db.execSQL("INSERT INTO \"manufacturers\" VALUES(NULL,NULL,NULL,?,?,?,?)",
new Object[] { sillyDate, sillyDate, someNumberAsString, name });
If you really want to do this in SQL, you have to use a hexadecimal blob literal and convert that to text:
"INSERT INTO \"manufacturers\" VALUES(NULL,NULL,NULL,'1970-01-01 00:00:00',"+
"'1970-01-01 00:00:00','35','A Priorite' || x'27');"
Please note that in SQL, quotes inside strings can be escaped by doubling them:
"INSERT INTO \"manufacturers\" VALUES(NULL,NULL,NULL,'1970-01-01 00:00:00',"+
"'1970-01-01 00:00:00','35','A Priorite''');"
I resolved my problem. Now it's working cool. I just changed my insert query to below one.
"INSERT INTO \"manufacturers\" VALUES(NULL,NULL,NULL,'1970-01-01 00:00:00','1970-01-01 00:00:00','35','A Priorite\047'');"
Thanks to #LS_dev and #CL. I accept #CL's answer.
Related
I've text type column named 'amountDesc' having some values in it. I want to get all values which have values greater than 100. I wrote a query but it's not giving the correct result.
Database as you can see as under.
i've tried this code:
String query = "SELECT amountDesc FROM increment WHERE amountDesc > 100";
Cursor rawQuery = getReadableDatabase().rawQuery(query, null);
if (rawQuery.moveToFirst()) {
while (!rawQuery.isAfterLast()) {
String value = rawQuery.getString(rawQuery.getColumnIndex("amountDesc"));
rawQuery.moveToNext();
Log.d("tvlateamoutn1", value);
}
}
and getting these values on Logcat:
500 50 200 50
as you can see its not correct values as I required > 100 values. I know its question of for most beginners level but I stuck in it. Kindly resolve.
I've text type column named 'amountDesc' having some values in it.
So in your table definition you have amountDesc TEXT or something equivalent?
From the documentation:
A column with TEXT affinity stores all data using storage classes NULL, TEXT or BLOB. If numerical data is inserted into a column with TEXT affinity it is converted into text form before being stored.
and:
If one operand has TEXT affinity and the other has no affinity, then TEXT affinity is applied to the other operand.
Since the column has text affinity, the other operand is being converted from the integer 100 to the string '100'. The string '50' is greater than the string '100' because '5' is greater than '1'. Thus, your query is returning exactly what you're asking it to return. You're just asking it something different from what you think you are.
If you want to treat the values in that column as integers and compare them accordingly, use INTEGER not TEXT when creating the table. A poor workaround for not picking the correct affinity for the data stored in the column is to cast the values to the appropriate type when using them in calculations... CAST(amountDesc AS INTEGER) > 100 or something like that.
(Reading and understanding the linked documentation on datatypes and affinity is essential for using sqlite effectively.)
Can you check data type of amountDesc in schema. If declared data type is string, you can not compare with integer (100).
I'm trying to store Regular Expressions-like values in Sqllite Database (most of them are special characters like regex) but i'm getting this error
android.database.sqlite.SQLiteException: near "com":
syntax error (code 1): , while compiling:
insert into sample (indexId,tag) values (1,'dfvfdv/ ;''e;g=[;''''/.'';.')
I am trying to parse escape sequence using this:
public String escapeSequence(String s){
return DatabaseUtils.sqlEscapeString(s);
}
but it's not helping, is there something i'm doing wrong? or is there any way to do this properly?
even tried
public String escapeSequence(String s){
String a=s.replaceAll("'", "''");
String b=DatabaseUtils.sqlEscapeString(a);
return b;
}
I'm trying to create a messenger kind of app, where i have to store Messages where message can be anything... (most of the time i don't have any control over that)
I've checked Is there a database that can store regex as values? but doesn't really answer my question...
The only char you have to escape is ' into double ''
that is, I'm using this wrapper:
mystring.replaceAll("'", "''")
http://www.sqlite.org/lang_expr.html
A string constant is formed by enclosing the string in single quotes ('). A single quote within the string can be encoded by putting two single quotes in a row - as in Pascal. C-style escapes using the backslash character are not supported because they are not standard SQL.
I've tested your code here: http://sqliteonline.com/
this doesn't work:
CREATE TABLE regexp (name VARCHAR2(20), regexp VARCHAR2(50));
insert into regexp (name,regexp) values {'test','dfvfdv/ ;''e;g=[;''''/.'';.'}
select * from regexp
but this works:
CREATE TABLE regexp (name VARCHAR2(20), regexp VARCHAR2(50));
insert into regexp (name,regexp) values ('test','dfvfdv/ ;''e;g=[;''''/.'';.')
select * from regexp
Just replace this figured parenthesis {} to those ()
Constructing SQL strings from values obtained from untrusted sources (such as user input) opens your app for SQL injection problems, and the kind of syntax issues you are seeing now.
Syntax issues and SQL injection can be avoided by using ? variables and binding the values.
On Android SQLite, you can use variable binding by using ContentValues with SQLiteDatabase methods that accept it such as insert() or update(). For selection or raw SQL, supply variables as ? in the SQL expression and the values in the selectionArgs or bindArgs array param.
I was curious if androids SQLiteDatabase insert method automatically handles type conversion.
Here is my example:
I have a csv file with a column name of age. Its type will be an INTEGER.
Lets say I have already created the database and table.
Now I am parsing the csv file with CSVReader, which parses each line and inserts each value into an index of a String[].
In order to insert each line of data into the database, I have to use a ContentValue object, which allows me to store values in it.
//Parse each line and store in line...
ContentValue values = new ContentValue();
values.put(KEY_AGE, line[1]); // Assume line[1] is the age
database.insert(table, null, values);
If I store the age value as a string (as seen above), and then insert it into the table, does Android handle the conversion to INTEGER before inserting it into the database?
I am asking this because I am trying to insert a bunch of tables into a database, and it looks much cleaner when I can just iterate through an array then explicitly state each put call, i.e:
Also if anyone has any design suggestions feel free to tell me.
CLEAN
int i = 0;
for(String s : TransitContract.Routes.COLUMN_ARRAY) {
values.put(s, line[i]);
i++;
}
UGLY
values.put(TransitContract.Routes.KEY_ROUTE_ID, line[0]);
values.put(TransitContract.Routes.KEY_AGENCY_ID, line[1]);
values.put(TransitContract.Routes.KEY_SHORT_NAME, line[2]);
values.put(TransitContract.Routes.KEY_LONG_NAME, line[3]);
values.put(TransitContract.Routes.KEY_DESCRIPTION, line[4]);
values.put(TransitContract.Routes.KEY_ROUTE_TYPE, Integer.parseInt(line[5]));
values.put(TransitContract.Routes.KEY_URL, line[6]);
values.put(TransitContract.Routes.KEY_COLOR, line[7]);
values.put(TransitContract.Routes.KEY_TEXT_COLOR, line[8]);
return mDatabase.insert(TransitContract.Routes.TABLE_NAME, null, values);
When you declare a column as INTEGER, SQLite will automatically convert strings to numbers, if possible.
See the documentation for Type Affinity.
If your ContentProvider doesn't restrict it (i.e. pass it directly to the SQLiteDatabase.insert() method), it should work. SQLite is not that picky about the types used in queries/inserts and the actual column type.
However, it would be best practice to parse and check the values before inserting. Otherwise you might actually insert a string which can't be parsed as integer and therefore retrieving the value might fail.
References:
Boolean datatype accepting string value and integer value
SQLite table with integer column stores string
I'm making an Android app and I have used an SQLite database. But I found out if you type characters like single quotes ('), (also for using as the primary key) the data won't be saved/retrieved correctly.
Is it a problem with me or is it true? If its true are there any more characters like that?
Thanks.
#bdares and #mu Thanks for the tips, but can you please tell me how to use placeholders and/or prepared statements in SQLite?
I have always used direct String concatenation before but now, as it appears that's a bad practice, I would like to use prepared statements and/or placeholders.
Possibly you'll have problems with characters like ASCII STOP and such non-printing characters, but if you use prepared statements and parameter binding, you won't have any trouble even with characters like '.
If you don't want to use parameter binding and prepared statements, you can replace all of your input ' with \' and you'll be fine.
SQL typically uses ' as its special character to tell when a string literal starts or stops. If your input has this character, it will stop treating the current line as a string and start treating it as commands. This is not a good thing, security wise. It also keeps you from inputting that character unless you "escape" it by placing a backslash in front of it, which tells SQL to ignore the ' and continue treating the following characters as a string until an unescaped ' is met. Of course, backslash literals are also escaped as double-backslashes.
Prepared statements typically look like this:
String sql = "INSERT INTO MYTABLE (NAME, EMP_NO, DATE_HIRED) VALUES (?, ?, ?)";
PreparedStatement ps = sqlite.prepareStatement(sql);
ps.setString(1, myString);
ps.setInt(2, myInt);
ps.setDate(3, myDate);
ps.executeUpdate();
Unfortunately, I don't know exactly what library you'd be using to access sqlite from Android, so I can't give you more details at this time.
SQLite statements use quotes -- single or double -- for strings. If you need to INSERT a string with (') for example, you can use double quotes (") to wrap the string:
INSERT INTO my_table (some_column) VALUES("'a string'");
Or the other way around:
INSERT INTO my_table (some_column) VALUES('"a string"');
(Of course, you will need to escape any (") in your Java code.)
An alternative is to use a SQLiteStatment (Prepared statement) and bindString()
As for the "characters allowed", SQLite internally stores strings (type TEXT) as UTF-8 or UTF-16. Android's build uses the default of UTF-8. Therefor, you can store any string you like.
SQLite supports the data types TEXT (similar to String in Java), INTEGER (similar to long in Java) and REAL (similar to double in Java). All other types must be converted into on of these fields before saving them in the database. SQLight itself does not validate if the types written to the columns are actually of the defined type, you can write an integer into a string column.
I've accidentally inserted the string datetime() into my database (in stead of the result of the function), and never saw my mistake until i did a listing of the data. The string "datetime()" is in the date field of all the records, yet the field type is datetime!
Is this normal for the sqllite that is on Android?? What's the point of field types then?
Yes, sqlite isn't strongly statically typed like most databases. When you assign a type to a column, it's more like a suggestion about how you'd want the value stored. If you create a column which is a text column, it will store numbers you put there as strings, since it can convert a number to a string for you. If you create a column with a integer type and try to store a string in it, it stores a string if it can't be converted to an integer. Read more about it here