I'm trying to store and array of bytes (byte[]) into a DB. I have the array of bytes, a content provider and a database. When I try to insert into the Blob the insert returns -1. Can somebody show me how to get this done.
Insert
byte[] inData = nw.receive();
ContentValues values = new ContentValues();
values.put(InDatabase.Columns.DATA, inData);
values.put(InDatabase.Columns.SIZE, inData.length);
NetService.this.getContentResolver().insert(InContentProvider.CONTENT_URI, values);
Content Provider
mDB = mDBHelper.getWritableDatabase();
Long rowId = mDB.insert(mDBHelper.tableName(), null, aValues);
Database
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE table " + TABLE_NAME + "(id INTEGER PRIMARY KEY AUTOINCREMENT, data BLOB, size INTEGER);");
}
Like I said If I don't put the values.put(InDatabase.Columns.DATA, inData), it works perfect.
So the implementation was right, the problem was with the SQLiteDatabaseHelper. I did not implement the onUpdate() method. Because my database already existed on the device with a different layout (the BLOB field did not exist) the insert method failed.
A quick uninstall of the .apk fixed the problem. I could also implement the onUpdate method so when the database version changes there is a table drop or update.
Related
I'm working on a project and don't understand this part of this code that I found online. (I have also looked at other examples and they do the exact same thing but I don't quite understand why)
When they are inserting something into the table, they have no value for the primary key. Could someone explain to me why that is the case?
Here is 2 examples of code that I found that do what I have stated above.
Thanks.
// As you can see a contact has 3 attributes.
int _id;
String _name;
String _phone_number;
// Where they create a table. As you can see the primary key is ID
#Override
public void onCreate(SQLiteDatabase db)
{
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
// Adding new contact
// This is what I don't understand. Why don't they get an ID for the contact.
// They only have values for the name and phone number when they insert it into the table.
public void addContact(Contact contact)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, contact.getName()); // Contact Name
values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone Number
// Inserting Row
db.insert(TABLE_CONTACTS, null, values);
db.close(); // Closing database connection
}
Here's another example but this is using a book.
A book has 3 attributes, an id (the primary key), an author and the book name. And once again, they don't get the value for the primary key.
public void addBook(Book book)
{
Log.d("addBook", book.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_TITLE, book.getTitle()); // get title
values.put(KEY_AUTHOR, book.getAuthor()); // get author
// 3. insert
db.insert(TABLE_BOOKS, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
because primary key is Autoincrement as it is an alias for ROWID.
from the documentation:
In SQLite, table rows normally have a 64-bit signed integer ROWID
which is unique among all rows in the same table. (WITHOUT ROWID
tables are the exception.)
You can access the ROWID of an SQLite table using one the special
column names ROWID, ROWID, or OID. Except if you declare an ordinary
table column to use one of those special names, then the use of that
name will refer to the declared column not to the internal ROWID.
If a table contains a column of type INTEGER PRIMARY KEY, then that
column becomes an alias for the ROWID. You can then access the ROWID
using any of four different names, the original three names described
above or the name given to the INTEGER PRIMARY KEY column. All these
names are aliases for one another and work equally well in any
context.
When a new row is inserted into an SQLite table, the ROWID can either
be specified as part of the INSERT statement or it can be assigned
automatically by the database engine. To specify a ROWID manually,
just include it in the list of values to be inserted. For example:
so in the examples you have given id is being assigned by database engine. for most of the use cases this is good enough.
You can create the table like
static final String DATABASE_CREATE = "create table "+TABLE_NAME+"( ID integer primary key autoincrement,user_name text,user_phone text,user_email text); ";
Then it will increment automatically
See this link http://www.freakyjolly.com/android-sqlite-integration/
http://www.freakyjolly.com/android-sqlite-how-to-insert-rows-in-database/
I am using an auto_increment primary key for the 'user' table. My question is, can I use that same User ID (Primary Key), as the primary key for the 'user log' table? Are there any major reasons why I shouldn't do this?
My idea on implementation:
To do this I would have the user create an entry (name,email pass, etc), once that's complete the 'User Log' is created by taking the key from the 'user' table and passing that into the 'user log' entry creation method as a foreign key? Or would it still be called the primary key at this point?
A simple code example would be great. Here is what I have:
// Create the table
public void onCreate(SQLiteDatabase db) {
// SQL statement to create book table
String CREATE_USER_TABLE = "CREATE TABLE userLog ( " +
"userID INTEGER PRIMARY KEY, " +
"date TEXT )";
// create directory table
db.execSQL(CREATE_USERLOG_TABLE);
}
//Add entry to the table using value from user
public void addEntry(UserLogEntry entry, UserEntry userEntry){
Log.d("addEntry", entry.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_USERID, userEntry.getUserID());
values.put(KEY_DATE, entry.getDate());
// 3. insert
db.insert(TABLE_USERLOG, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
So that won't work thanks to CL for pointing that out. I'll need to have a unique key and add the userid's as a new column. I'll just pull the userid from the users table when creating the userslog and that should solve that issue.
I have a little Problem with an insert-Statement in my Android-App.
Here is the code:
public void addNote(Note noteItem, int modulNummer){
SQLiteDatabase db = getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(COLUMN_NOTE, noteItem.getNote());
cv.put(COLUMN_NOTEBESCHREIBUNG, noteItem.getBeschreibung());
cv.put(COLUMN_MODULID_FK, modulNummer);
db.insert(NOTETABLE, null, cv);
}
Now my problem. The first column in my table is an auto increment pk. And so i want to skip the first column and i want to begin the insert in the second column. How can i skip this first column?
Update
I've already deleted the .put for the first column. "COLUMN_NOTE" is my second column.
My table-structure looks like this:
id INTEGER AUTO INCREMENT
note double
beschreibung TEXT
modul_id INTEGER
UPDATE 2
I don't know why, but now it works. Thx for your help guys.
If you have a table like the following one:
private final String TAB_GROUP_ADD = "CREATE TABLE groups (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, description TEXT NOT NULL);";
And you use the following insert command:
ContentValues values = new ContentValues();
values.put(K_TITLE, title);
values.put(K_DESCRIPTION, description);
db.insert(TAB_GROUP, null, values);
Everything should go fine. The primary key field "id" will no be filled in by Java and the SQLite Database will do it for you.
I've gone through many examples here, but all seem complicated and most of them are for large data. I'm new to both Android and also SQL. What I want to do is just pre-populate my SQL database with some data.
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE restaurants (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, type TEXT, notes TEXT, feed TEXT, lat REAL, lon REAL);");
ContentValues cv=new ContentValues();
cv.put("name", "Hi");
cv.put("address", "There");
cv.put("type", "delivery");
cv.put("notes", "");
cv.put("feed", "");
cv.put("lat", "");
cv.put("lon", "");
getWritableDatabase().insert("restaurants", "name", cv);
}
There is no error but unfortunately no data is inserted as well. This should be very simple, please help me?
Use db.insert("restaurants", "name", cv);
Your approach is fine, inside SQLiteOpenHelper#onCreate() is the right place to put initial data since that is where you create the database in the state you like it to be.
But inside onCreate you use db.insert("restaurants", "name", cv) directly. You are not finished to create the writable database you try to get via getWritableDatabase() at that point. Not sure if that is the problem but it could be.
I want to enter name and phone number from two edit text.i use two buttons to save and show it in emulator using list view.After entering name and when i click save button how to check whether i have already entered the same name. i am new to android explanation will be really helpful.
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+tbname+"("+Key_id+" INTEGER PRIMARY KEY AUTOINCREMENT, "+Key_name+" TEXT,"+Key_mobile+" TEXT)");
}
public void n(String aa, String bb) {
SQLiteDatabase db=this.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(Key_name, aa);
cv.put(Key_mobile, bb);
db.insert(tbname, Key_name, cv);
db.close();
}
public Cursor cr()
{
SQLiteDatabase db=getReadableDatabase();
String [] colms=new String[]{Key_id+" as _id",Key_name,Key_mobile};
Cursor cur=db.query(tbname, colms, null, null, null, null, null);
cur.moveToFirst();
return cur;
}
I would start with changing your table definition by adding the NOT NULL and UNIQUE constraints.
db.execSQL("CREATE TABLE "+tbname+"("+Key_id+" INTEGER PRIMARY KEY AUTOINCREMENT, "+Key_name+" TEXT NOT NULL UNIQUE,"+Key_mobile+" TEXT)");
Then you have a choice of methods to use for your insert. You can use:
insertOrThrow will return the id of your new record, or -1 on an error (and a constraint failure of not having a unique name would be an error).
insertWithOnConflict will return the id of the new record OR the primary key of the existing row if the input param 'conflictAlgorithm' = CONFLICT_IGNORE OR -1 if any error.
Personally, I would use insertWithOnConflict with the CONFLICT_IGNORE flag set. That way you can get the row id back for the duplicate record (as well as not letting the duplicate get entered).
Put UNIQUE in your table field definition an then use insertOrThrow. If you insert the same, insertOrThrow will cause an exception, you can intercept it.