I'm having a lot of trouble with SQLiteDatabase command. I have loaded up spatialite and enabled the extension. I want one of my values to be the output of the MakePoint function so I have a content value like this:
values.put("Location", "MakePoint(43.2, 27.345, 4326)");
When this is passed into SQLiteDatabase.Update() it's escapsed so that the resulting string ends up being "UPDATE Targets SET Location='MakePoint(43.2, 27.345, 4326)'" SQLite hates this and throws an exception.
Is there an easy way around this? Right now I'm trying to build up the string manually since I can't use Update.
SQLiteDatabase was not designed for the SpatiaLite extension.
update() supports only simple values, not generic expressions; you cannot use it to insert geographic objects.
The only way to execute your command is to build it manually an run it through execSQL().
You could write your own database wrapper object that understands SpatiaLite data types.
I figured it out. I have to do a "SELECT MakePoint(43.2, 27.345, 4326)" first and then insert that into Location.
Related
I am new using sqflite, I come from android studio where by for's I build a query with more than 1 row, which was this:
INSERT OR REPLACE INTO clientes (codigo, empresa, nombre, e_mail) VALUES (?,?,?,?),(?,?,?,?)
then again using for, I inserted the values with the bind.
My problem is that now I'm trying to do the same function but in Flutter .. and I can't find the way because i didnt find any function called "binds" like in android studio .. I know that with Flutter it is easier to handle the Maps with SQFLite but I don't know the way ... at the moment I have this dynamically armed query:
INSERT OR REPLACE INTO clientes (codigo, empresa, nombre, e_mail) VALUES (?,?,?,?),(?,?,?,?)
How do I now pass the values dynamically in flutter?
because this executes it and inserts it, but of course in the DB what you see is "NULL NULL NULL NULL" clearly because I am not passing the values to the arguments ... could you help me or guide me on how to do it?
I was thinking that if, I could pass those values dynamically from a map? How should I do some practical example could you give me?
or with a list? for ex
[{2, asd, asd, asd#mail.com}, {3, asd, asd, asd#mail.com}]
and dynamically insert each 1 of those 2 items as arguments ... could you give me a practical example if this is possible?
thanks since now
I didn't find anything inside the docs. What is the propper way to alter a view in room? I tried with the way to create a migration, drop the existing view and create a new one with the sql text, but I still get the room error with the difference between "expected and found scheme" (even the sql-s seems identical, I checked with a comparison tool)
For everyone, obviously room is comparing raw strings not the table/view that is being generated from the provided sql text/entity. The problem in my case was that I had an extra space after a comma inside my altered view sql text, which led to a false result when comparing to the sql text room was generating from my entity (even though the generated views where the same).
For me it's a little bit of a surprise that room is using the raw sql strings in order to check for integrity..., but now I know.
Edit:
just one tip to always get the exact same sql string. Change the entity as you wish, and compile the app. Even if it crash, room will generate the right sql text for the change that was made inside the entity. Then just open the generated YOURDATABASE_Impl file and search for the table/view.
I want to use SQLite's built-in function datetime('now','localtime') in my Android code to save date in a database field of TEXT type. I am already able to do this in sqlite3 terminal as follows:
sqlite> INSERT INTO test (Name, NO, date) VALUES('John', 1151, datetime('now','localtime'));
sqlite> SELECT * FROM test;
John|1151|2017-06-23 17:38:29
This is fine, until I want to use the datetime() function with Android's ContentValues. I use it like this:
ContentValues values=new ContentValues();
values.put(Entry.NAME,nameString);
values.put(Entry.NO,noInt);
values.put(Entry.DATE,"datetime('now','localtime')");
/// ....
getContentResolver().insert(Entry.CONTENT_URI,values);
Then, my listview shows everything fine, but for the date's textview I exactly see the text datetime('now','localtime') instead of the date that I expected to be saved in the database e.g. 2017-06-23 17:38:29. How can I solve this problem? Is there a way I can use built-in SQLite functions with ContentValue objects for inserting data?
How can I solve this problem?
Do not use insert(). Use execSQL().
Is there a way I can use built-in SQLite functions with ContentValue objects for inserting data?
No, sorry.
Simple question: do case expressions work in Android?
I'm trying to implement a expression that checks the user value at the insert time and does some modification according to it. I know the expression is syntactically correct because it works at the SQLite prompt inside the INSERT command. However, when I try to use it in Android (using SQLiteDatabase.insert()) the expression is treated as a String. I have also tried to implement it using some of the core SQLite functions and this new expression is also treated as a String. Any thoughts why this happens?
Edit 1: rawQuery() is also not an option. The method is ignored. Here are the logcat messages that appear to be related to the method call.
The insert method treats all values as actual values, not SQL expressions.
So when you use code like this:
cv.put("Col1", "CASE X WHEN 42 THEN 'y' END");
db.insert("Tab", null, cv);
then it is assumed that the string is just a string, and that you want exactly this string to be inserted. This results in a SQL command like this:
INSERT INTO Tab(Col1) VALUES('CASE X WHEN 42 THEN ''y'' END')
If you want to do anything more complex than the simple case that insert() was designed for, you must use rawQuery instead and build the entire SQL statement by hand.
Thanks for the answers, but I solved my problem using (despite not being recommended on documentation) execSQL().
I am currently studying SQLite and I have found that it uses various classes like ContentValues for insertion and updation... I was wondering whether I have to follow the given way or can I write a normal SQL query and use db.execSQL() method to execute them?
Will it bring any inconsistency to my database because with these all "extra" steps doesnt it stop the flow of the query and I feel it would be faster if we use a query directly.
You can do any SQL command you want with db.execSQL except select command or any other SQL command that return data (you use db.rawQuery() for this). The classes used are helper classes that make it easy for you to manipulate DBs (try inserting 100 rows with 20 columns each using ContentValues and db.execSQL and you will get the point). For small tables it will not differ much (and you will not cause inconsistecies), however, for large tables with inputs that depend on user interface or use calculations, it might be useful to have a class like ContentValues with its helper methods.
Yes you can definitely use this way like using
myDB.execSQL("INSERT INTO MyTable VALUES ('fffff', 'numb', 20)");
to insert values but only when you are using database for small queries.
Also there are some flaws using direct methods which gets removed using ContentValues
For example,try to insert a blob into the database using this method ,you will get a null bitmap while converting the retrieved data to bitmap.But when you insert using ContentValues,you will get the correct data i.e you will be able to convert that into Bitmap.