I have an xml file as shown in the picture. I want two things, first, I want to insert pre-defined values in my sqlite database on onCreate method using an arraylist (or any method). Then secondly, I want to use those values from the arraylist, now in my database, to populate the two spinners(Producer and Product).
I have a database file that handles the db connections and methods and this is what I have done so far. This code is inside my onCreate method
db.execSQL("CREATE TABLE " + TABLE_PRODUCT + "("
+ PRODUCT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + PRODUCT_NAME + " TEXT,"
+ PRODUCER_FK + " INTEGER" + " FOREIGN KEY(PRODUCER_FK) REFERENCES TABLE_PRODUCER(PRODUCER_ID))");
ContentValues contentv=new ContentValues();
contentv.put("name", "Soya Seed");
getWritableDatabase().insert("TABLE_PRODUCT", null, contentv);
db.execSQL("CREATE TABLE " + TABLE_PRODUCER + "("
+ PRODUCER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + PRODUCER_NAME + " TEXT,"
+ PRODUCER_ADDRESS + " TEXT,"
+ PRODUCER_PHONE + " TEXT UNIQUE," + PRODUCER_EMAIL + " TEXT,"
+ CONTACT_PERSON + " TEXT" + ")");
ContentValues cv=new ContentValues();
cv.put("name", "ZamSEED");
cv.put("address", "Luanda");
cv.put("phone", "+244977654321");
cv.put("email", "demo#zamseed.com");
cv.put("contact_name", "Mr. Tembo");
getWritableDatabase().insert("TABLE_PRODUCER", null, cv);
Then I have an inventory file that reads from the database to get values from the product and producers tables to populate the spinners.
My challenge is how can I tell if my db.execSQL is actually successful?
And how would I use an arraylist to insert values in the database?
NOTE: the app runs fine when I ran it but I am not sure if the tables are created and values inserted. Am a newbie to Android programming, thanks.
After some time of research into this, I found this article here that led me to see the actual tables of my db.execSQL command and the data contained. In Ubuntu:
cd /path/to/my/sdk/platform-tools
./adb shell
run-as <app package name>
cd /data/data/<app package name>/databases
ls
chmod 666 <database file name>
sqlite3 <database file name>
> (semi-colon terminated commands can be run here to query the data)
> .exit
(copy full database path)
exit
Then use sqlite3 commands to work on database > (semi-colon terminated commands can be run here to query the data)
DatabaseHelper.java
public ArrayList<String>getProductList(){
ArrayList<String>products = new ArrayList<String>();
SQLiteDatabase qDB = getReadableDatabase();
String columns[]=new String[]{PRODUCT_NAME};
Cursor cursor = qDB.query(TABLE_PRODUCT,columns,null,null,null,null,null);
while (cursor.moveToNext()){
String produectName = cursor.getString(1);
products.add(productName);
Log.e("e",products);
}
return products;
}
SomeActivity.java
spinnerProducts = (Spinner) findViewById(R.id.spinnerProducts);
ArrayList<String>productsList = new DatabaseHelper(context).getProductsList();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(context,android.R.layout.simple_list_item_1,productsList);
spinnerProducts.setAdapter(arrayAdapter);
...
//same logic for Producers list
My challenge is how can I tell if my db.execSQL is actually successful?
It was successful if it did not throw an exception.
However calling getWritableDatabase() in onCreate() is an error since that results in recursion: getWritableDatabase() triggers a call to onCreate() in the first place. You should use the SQLiteDatabase passed to you as a param instead.
If you did not see an exception about the recursive call then you already had a database file with the correct version. You can uninstall your app to clean up its data and then install and run it again to make onCreate() run again.
And how would I use an arraylist to insert values in the database?
Use a loop to iterate the list and insert values one by one.
Related
I want to change a single column inside a row. I'm trying to update the value inside "remindOnDate" field to "reminder" in the "tasks" table.
I tried a few things but they all work only when remindOnDate is null. Once it has a value stored in it, update won't work on it. I don't know why. What am I doing wrong? If the statement is wrong then it shouldn't work even when remindOnDate is null.
I tried this:
ContentValues editTask = new ContentValues();
editTask.put("remindOnDate", reminder);
database.update("tasks", editTask, "_id = ?", new String[]{id+""});
I also tried the following instead of the last line:
database.update("tasks", editTask, "_id = " + id, null);
Here is another thing I tried:
String createQuery = "UPDATE tasks SET remindOnDate = '" + reminder + "' WHERE _id = " + id + ";";
database.execSQL(createQuery);
I have two tables; a 'parent' and a 'child' table. (not SQLite defitinions, just something i call them)
Everytime a child-object is created, it is assigned the value 0 in one of its columns.
When a new parent-object is created, every unassigned child-object, has to update the value mentioned before, to the parent-object's ID. My code looks like this:
public long createWorkout(String workoutName){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, workoutName);
//Creates a new parent-object (a workout - the childs are exercises)
//the generated ID is returned as a long (workout_pk_id)
long workout_pk_id = db.insert(TABLE_WORKOUT, null, values);
//Selects all objects in the child-table with KEY_WORKOUT_ID = 0 (the column mentioned before)
String selectQuery = "SELECT * FROM " + TABLE_EXERCISE + " WHERE " + KEY_WORKOUT_ID + " == " + 0;
Cursor cursor = db.rawQuery(selectQuery, null);
//Takes each found object with value 0, and updates the value to the returned parent-ID from before.
if (cursor.moveToFirst()) {
do {
String k = "UPDATE " + TABLE_EXERCISE + " SET " + KEY_WORKOUT_ID + " == " + workout_pk_id;
db.execSQL(k);
} while (cursor.moveToNext());
}
return workout_pk_id;
}
But for some reason this doesn't work. The ID the childs/exercises remains 0. Can you help me?
I don't know if the error is somewhere in the setup of my tables, in that case i could provide some more information.
Thanks in advance. /Jeppe
EDIT: This is used in android, and I have debugged and verified that the workout_pk_id is returned, 45 objects are found in the selectQuery and yet it doesn't work. I also tried ContentValues to update the values, didn't work.
Edited the " == " to " = ", but the value is still not updated.
This is from eclipse - I've created a workout called "test", with the ID 160.
The exercise "test1" has the ID 430 (unique) but the workout_id is still 0.
It's been awhile since I did any Android stuff but I believe the "==" operator is incorrect:
String k = "UPDATE " + TABLE_EXERCISE + " SET " + KEY_WORKOUT_ID + " == " + workout_pk_id;
The operator you're using is a comparative operator, "=" is the assignment operator.
I also believe there is a better way to do what you are trying to do, currently refreshing my memory on Android so I'll get back to you. In the meantime tell me if replacing the operator works
Yeah so another way you can do this is by using subqueries. So it would look something like:
UPDATE TABLE_EXCERCISE SET KEY_WORKOUT_ID = WORKOUT_PK_ID WHERE KEY_WORKOUT_ID =
(
*subquery here to select parent object ids*
)
Here's a link to help:
http://www.tutorialspoint.com/sqlite/sqlite_sub_queries.htm
Let me know how this works for you.
I think you have to look to your update query.
It has to be:
String k = "UPDATE " + TABLE_EXERCISE + " SET " + KEY_WORKOUT_ID + " = " + workout_pk_id;
Look at the "=" between KEY_WORKOUT_ID and workout_pk_id.
I have a database full of tweets. When the user clicks refresh, I want to grab tweets newer than an ID (which I know how to do). After I grab the tweets, I want to insert them before ID 0, so tweet with ID 0 is no longer the first tweet, and instead replaced with the newer tweets.
I have searched and I have no idea how to do this.
Here is the code I am using to add the user's timeline on first launch:
public void addTimemline(Timeline timeline){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COL_TEXT, timeline.getText());
values.put(COL_TWEET_ID, timeline.getTweetId());
values.put(COL_SCREEN_NAME, timeline.getTwitterScreenName());
values.put(COL_REAL_NAME, timeline.getRealName());
values.put(COL_FAVORITE_COUNT, timeline.getFavoriteCount());
values.put(COL_RETWEET_COUNT, timeline.getRetweetedCount());
values.put(COL_HASHTAG_ENTITIES, timeline.getHashtagEntities());
values.put(COL_USER_MENTION_ENTITIES, timeline.getUserMentionEntities());
values.put(COL_URL_ENTITIES, timeline.getUrlEntities());
values.put(COL_MEDIA_ENTITIES, timeline.getMediaEntities());
db.insertOrThrow(TABLE_TWEETS, null, values);
db.close();
}
Create statement:
private static final String TABLE_TWEETS_CREATE = "create table "+TABLE_TWEETS+" ("
+ Tweets.COL_ROW_ID + " integer primary key autoincrement not null, "
+ Tweets.COL_TEXT + " text not null, "
+ Tweets.COL_TWEET_ID + " text,"
+ Tweets.COL_SCREEN_NAME + " text,"
+ Tweets.COL_REAL_NAME + " text,"
+ Tweets.COL_FAVORITE_COUNT + " text,"
+ Tweets.COL_RETWEET_COUNT + " text,"
+ Tweets.COL_HASHTAG_ENTITIES + " text,"
+ Tweets.COL_USER_MENTION_ENTITIES + " text,"
+ Tweets.COL_URL_ENTITIES + " text,"
+ Tweets.COL_MEDIA_ENTITIES + " text);";
As you have it set up, you cannot do that. You are telling the DB to autoincrement the key, so it will give you the next available slot that has not been used yet. Meaning if you have four records and delete the last one, you will still get the fifth slot the next time you insert a record. It will not allow you tot set the id yourself or insert a record before the last one inserted.
You could change to manually managing the IDs but that is much more work and prone to errors, and I would strenuously recommend you avoid doing so.
You should really investigate the ORDER BY keyword for SQLite. That will sort the cursor into the order you define in your query rather than relying on the id order of the records. If you put a time stamp of some kind in your data structure you could then sort in reverse order on that when you pull the cursor.
You can find full documentation of the SQLite ORDER BY keyword here.
You have not said if you are using raw SQL or any of the android SQLite functions, so you may also want to look at the android sqlite insert function here.
I am working on an android app and I am creating a database called HealthDev.db that has a table called rawData that has 4 columns:
_id, foreignUserId, data, timeStamp
I have worked with the program sqlite3 in the bash shell and have figured out that I can have a time stamp column with the following column schema parameter:
timeStamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
so when I created the table I used:
create table rawData(_id integer primary key autoincrement, foreignUserId integer, data real, timeStamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
This worked fine in the bash.
Then I practiced in the sqlite3 and know that when inserting into the timeStamp column and using the function time('now') as a value to store it actually stores a time stamp in the form HH:MM:SS in Universal Coordinated Time.
So now translating that into java for the android app, I used the following code below. This way the table automatically generates about 20 rows when the onCreate is called. This is just for testing if I am passing the time('now') correctly in java.
// Below are variables to the database table name and the
// database column names.
public static final String TABLE_RAW_DATA = "rawData";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_FOREIGN_USER_ID = "foreignUserId";
public static final String COLUMN_DATA = "data";
public static final String COLUMN_TIME_STAMP = "timeStamp";
// Database creation sql statement.
private static final String DATABASE_CREATE = "create table "
+ TABLE_RAW_DATA
+ "("
+ COLUMN_ID + " integer primary key autoincrement, "
+ COLUMN_FOREIGN_USER_ID + " integer, "
+ COLUMN_DATA + " real, "
+ COLUMN_TIME_STAMP + " TIMESTAMP DEFAULT CURRENT_TIMESTAMP"
+ ");";
// initializes the columns of the database given by passing the DATABASE_CREATE
// sql statement to the incoming database.
public static void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
// For testing
ContentValues contentValues = new ContentValues();
System.out.println("The database is open? " + database.isOpen());
for (int i = 0; i < 20; i++)
{
contentValues.put( COLUMN_FOREIGN_USER_ID, 8976);
contentValues.put( COLUMN_DATA, Math.random()*100 );
contentValues.put( COLUMN_TIME_STAMP, " time('now') " );
database.insert( TABLE_RAW_DATA, null, contentValues );
//contentValues = new ContentValues();
}
}
After running this code in an eclipse emulator I then pulled the database file from the file explorer in DDMS view mode for eclipse android projects. Then I opened the database in a bash shell and then selected all the columns from the table rawData to show it on the shell. I noticed that the time('now') was treated as a string and not a function. To prove that the time('now') function worked I manually inserted a new row using time('now') for the timeStamp value. Then re selected all the columns to show them again. It successfully printed the time stampe as HH:MM:SS.
I am thinking there might be a difference in the enviroments? The bash shell recognizes the function time('now'), which was written in c right?, because I have the sqlite3 program in the bash? Yet in eclipse when I use a SQL database and use the insert it treats the time('now') as a string. Keep in mind I am working in a Windows 7 os. I am accessing the bash as a client (SSH Secure Shell) from my school which is the host.
My main question is it possible to code it so that way it recognizes the time('now') function?
Since the default for the column is CURRENT_TIMESTAMP, what if you leave out entirely this line:
contentValues.put( COLUMN_TIME_STAMP, " time('now') " );
Won't it now insert the current timestamp into that column by default?
I'm trying to take some values stored from EditText fields and store them into my SQLLite DB.
I have the following String variables:
site_name
_address
_user
_pass
Here is the Sql command I'm trying to use:
SQLiteDatabase db = openOrCreateDatabase("SiteManager", MODE_PRIVATE,
null);
db.execSQL("CREATE TABLE IF NOT EXISTS SiteTable (Name VARCHAR, Address VARCHAR, Usernname VARCHAR, Password VARCHAR, PORT INT(4), Passive BIT);");
db.execSQL("INSERT INTO SiteTable VALUES ('" + site_name + "','"
+ _address + "','" + _user + "','" + _pass + "'," + _port + ","
+ _passive + ");");
I'm checking the value like this in another Activity:
SQLiteDatabase db = openOrCreateDatabase("SiteManager",
MODE_PRIVATE, null);
Cursor c = db.rawQuery("SELECT * FROM SiteTable", null);
c.moveToFirst();
Toast.makeText(this, c.getString(c.getColumnIndex("Name")),
Toast.LENGTH_LONG).show();
db.close();
In the debugger it's showing c as not having any values but the column names are there. So this makes me think there's something wrong with the way I'm trying to use variables in my SQL statement. What am I doing wrong?
If you're using the standard Android binding, whose Javadoc is here, then you can find the right code to call by looking at the Javadoc for an overload of execSQL. See SQLiteDatabase.html#execSQL(String, Object[]).
Now, the Javadoc says that execSQL is not to be used for SELECT/INSERT/UPDATE/DELETE. Instead, there are three insertXXX methods, each of which takes additional data in a ContentValues object. So, you construct that object, which looks like a Map, with the new row's data.
This is the answer you are searching
sqLiteDatabase.execSQL("insert into userTable (username,name,password,email)
values('"+username+"','"+name+"','"+password+"','"+email+"') ");