I'm unable to fetch the data although I'm able to add data. I have two questions here: What is the purpose of the primary key and how can I implement it? In my code, if I give the same values multiple times then it also gets accepted.
//Check this statement
db.execSQL("create table mtable (_Id Integer auto_increment, name Text Primary key , mail Text)");
Now,my 2nd major problem..
Why am I not able to fetch the data from the database ?
My two java classes are as follows:
MainActivity.java
package com.apna.mydatabase;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity implements OnClickListener {
Button save,fetch,update,Delete;
EditText edtname,edtmail,afetch;
MySqlOpenHelper ab,db;
SQLiteDatabase sql,sql1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edtname=(EditText) findViewById(R.id.editText1);
edtmail=(EditText)findViewById(R.id.editText2);
afetch=(EditText) findViewById(R.id.editText3);
save=(Button) findViewById(R.id.button1);
fetch=(Button) findViewById(R.id.button2);
update=(Button) findViewById(R.id.button3);
Delete=(Button)findViewById(R.id.button4);
save.setOnClickListener(this);
fetch.setOnClickListener(this);
ab=new MySqlOpenHelper(MainActivity.this);
sql=ab.getWritableDatabase();
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.button1:
ContentValues cv=new ContentValues();
cv.put("name", edtname.getText().toString());
cv.put("mail",edtmail.getText().toString());
long result=sql.insert("mtable", "nullCo", cv);
if (result>0)
{
Toast.makeText(MainActivity.this, "Saved at"+result, 5000).show();
edtname.setText(" ");
edtmail.setText(" ");
}
else
{
Toast.makeText(MainActivity.this, "Not Saved"+result, 5000).show();
}
break;
case R.id.button2:
db= new MySqlOpenHelper(MainActivity.this);
sql1=db.getReadableDatabase();
String a=afetch.getText().toString();
Cursor c=sql1.rawQuery("Select * from mtable where _id ="+a,null );
String str=null,str1=null;
if(c.getCount()>0)
{
while(c.moveToNext())
{
str=c.getString(c.getColumnIndex("name"));
str1=c.getString(c.getColumnIndex("mail"));
}
edtname.setText(str);
edtmail.setText(str1);
}
else
{
Toast.makeText(MainActivity.this,"Invalid record",5000 ).show();
}
}
}
}
MySqlOpenHelper.java
package com.apna.mydatabase;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class MySqlOpenHelper extends SQLiteOpenHelper {
public MySqlOpenHelper(Context context)
{
super(context, "Mynew", null,1);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL("create table mtable (_Id Integer auto_increment, name Text Primary key , mail Text)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
It would be my pleasure to get the required results.
what the purpose of primary key
A primary key is a special relational database table column (or combination of columns) designated to uniquely identify all table records.
A primary key’s main features are:
It must contain a unique value for each row of data.
It cannot contain null values.
See reference.
how to implement it
Primary Key can also be a composite key meaning two columns say in your case _Id and name could both be primary key. Satisfying the above conditions.
EDIT:
It is not advisable to have only name as the primary key since names can recur and defeat the purpose of the primary key. For a composite key you could :
db.execSQL("create table mtable (_Id Integer auto_increment, name Text not null,primary key (_Id,name) , mail Text)")
Simply put I have achieved it as:
create table mtable (_Id Integer identity, name varchar not null,primary key (_Id,name) , mail Text)
For example:
If you enter name say Anand and insert the record. Say another person is name Anand you insert it again it would defeat the purpose of the primary key as in relational databases it is meant to uniquely identify a record which in this case won't happen.
if i give same values multiple times then it also accept it
You can insert multiple values having the same primary key because you haven't specified your primary key to be unique or identity as in :
db.execSQL("create table mtable (_Id Integer auto_increment, name Text Primary key , mail Text)");
Why am I not able to fetch the data from the database ?
Your code seems to be fine. Debug it and see if the cursor contains anything and is not null. You could check first:
if (cursor != null) {
//move cursor to first row
if (cursor.moveToFirst()) {
do {
// Get version from Cursor
String name = cursor.getString(cursor.getColumnIndex("name"));
//more code
// move to next row
} while (cursor.moveToNext());
}
}
Update:
If you try to reinsert a row with the same primary key you would get the error that primary key should be unique and the primary key includes in itself the not null and unique traits so no need to specify these with it.
Related
I want to save the data from web site in sqlite database
WeatheDbHelper.java
/*sqlite database handler*/
package com.example.admin.sunshine.app.data;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by admin on 18/02/2016.
*/
public class WeatherDbHelper extends SQLiteOpenHelper{
private static final int DATABASE_VERSION=2;
static final String DATABASE_NAME="weather.db";
public WeatherDbHelper(Context context)
{
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase)
{
final String SQL_CREATE_LOCATION_TABLE="CREATE TABLE"+ WeatherContract.LocationEntry.TABLE_NAME+"("+
WeatherContract.LocationEntry._ID+"INTEGER PRIMARY KEY,"+
WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING+"TEXT UNIQUE NOT NULL,"+
WeatherContract.LocationEntry.COLUMN_CITY_NAME+"TEXT NOT NULL,"+
WeatherContract.LocationEntry.COLUMN_COORD_LAT+"REAL NOT NULL,"+
WeatherContract.LocationEntry.COLUMN_COORD_LONG+"REAL NOT NULL"+
");";
final String SQL_CREATE_WEATHER_TABLE="CREATE TABLE" + WeatherContract.WeatherEntry.TABLE_NAME+"("+
WeatherContract.WeatherEntry._ID +"INTEGER PRIMARY KEY AUTOINCREMENT,"+
WeatherContract.WeatherEntry.COLUMN_LOC_KEY +"INTEGER NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_DATE +"INTEGER NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC +"TEXT NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID +"INTEGER NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_HUMIDITY +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_PRESSURE +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_WIND_SPEED +"REAL NOT NULL,"+
WeatherContract.WeatherEntry.COLUMN_DEGREES +"REAL NOT NULL,"+
"FOREIGN KEY("+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY +")REFERENCES "+
WeatherContract.LocationEntry.TABLE_NAME +"("+ WeatherContract.LocationEntry._ID+"),"+
"UNIQUE ("+ WeatherContract.WeatherEntry.COLUMN_DATE+","+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY+
") ON CONFLICT REPLACE);";
sqLiteDatabase.execSQL(SQL_CREATE_WEATHER_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase,int oldVersion, int newVersion)
{
sqLiteDatabase.execSQL("DROP TABLE IF EXIST"+ WeatherContract.LocationEntry.TABLE_NAME);
sqLiteDatabase.execSQL("DROP TABLE IF EXIST"+ WeatherContract.WeatherEntry.TABLE_NAME);
onCreate(sqLiteDatabase);
}
}
TestDb.java for testing the create table
/*creating the SQLite database
package com.example.admin.sunshine.app.data;
/**
* Created by admin on 22/02/2016.
*/
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;
import java.util.HashSet;
public class TestDb extends AndroidTestCase {
public static final String LOG_TAG = TestDb.class.getSimpleName();
// Since we want each test to start with a clean slate
void deleteTheDatabase() {
mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME);
}
/*
This function gets called before each test is executed to delete the database. This makes
sure that we always have a clean test.
*/
public void setUp() {
deleteTheDatabase();
}
/*
Students: Uncomment this test once you've written the code to create the Location
table. Note that you will have to have chosen the same column names that I did in
my solution for this test to compile, so if you haven't yet done that, this is
a good time to change your column names to match mine.
Note that this only tests that the Location table has the correct columns, since we
give you the code for the weather table. This test does not look at the
*/
public void testCreateDb() throws Throwable {
// build a HashSet of all of the table names we wish to look for
// Note that there will be another table in the DB that stores the
// Android metadata (db version information)
final HashSet<String> tableNameHashSet = new HashSet<String>();
tableNameHashSet.add(WeatherContract.LocationEntry.TABLE_NAME);
tableNameHashSet.add(WeatherContract.WeatherEntry.TABLE_NAME);
boolean b = mContext.deleteDatabase(WeatherDbHelper.DATABASE_NAME);
SQLiteDatabase db = new WeatherDbHelper(
this.mContext).getWritableDatabase();
assertEquals(true, db.isOpen());
// have we created the tables we want?
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);
assertTrue("Error: This means that the database has not been created correctly",
c.moveToFirst());
// verify that the tables have been created
do {
tableNameHashSet.remove(c.getString(0));
} while( c.moveToNext() );
// if this fails, it means that your database doesn't contain both the location entry
// and weather entry tables
assertTrue("Error: Your database was created without both the location entry and weather entry tables",
tableNameHashSet.isEmpty());
// now, do our tables contain the correct columns?
c = db.rawQuery("PRAGMA table_info(" + WeatherContract.LocationEntry.TABLE_NAME + ")",
null);
assertTrue("Error: This means that we were unable to query the database for table information.",
c.moveToFirst());
// Build a HashSet of all of the column names we want to look for
final HashSet<String> locationColumnHashSet = new HashSet<String>();
locationColumnHashSet.add(WeatherContract.LocationEntry._ID);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_CITY_NAME);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_COORD_LAT);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_COORD_LONG);
locationColumnHashSet.add(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING);
int columnNameIndex = c.getColumnIndex("name");
do {
String columnName = c.getString(columnNameIndex);
locationColumnHashSet.remove(columnName);
} while(c.moveToNext());
// if this fails, it means that your database doesn't contain all of the required location
// entry columns
assertTrue("Error: The database doesn't contain all of the required location entry columns",
locationColumnHashSet.isEmpty());
db.close();
}
/*
Students: Here is where you will build code to test that we can insert and query the
location database. We've done a lot of work for you. You'll want to look in TestUtilities
where you can uncomment out the "createNorthPoleLocationValues" function. You can
also make use of the ValidateCurrentRecord function from within TestUtilities.
*/
public void testLocationTable() {
String testLocationSetting = "99705";
String testCityName = "North Pole";
double testLatitude = 64.7488;
double testLongitude = -147.353;
// First step: Get reference to writable database
SQLiteDatabase db = new WeatherDbHelper(
this.mContext).getWritableDatabase();
assertEquals(true, db.isOpen());
// Create ContentValues of what you want to insert
// (you can use the createNorthPoleLocationValues if you wish)
ContentValues locationValues = new ContentValues();
locationValues.put(WeatherContract.LocationEntry.COLUMN_LOCATION_SETTING, testLocationSetting);
locationValues.put(WeatherContract.LocationEntry.COLUMN_CITY_NAME, testCityName);
locationValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LAT, testLatitude);
locationValues.put(WeatherContract.LocationEntry.COLUMN_COORD_LONG, testLongitude);
// Insert ContentValues into database and get a row ID back
long locationRowId;
locationRowId = db.insert(WeatherContract.LocationEntry.TABLE_NAME, null, locationValues);
assertTrue(locationRowId != -1);
// Query the database and receive a Cursor back
Cursor c = db.query(WeatherContract.LocationEntry.TABLE_NAME,
null, //all columns
null, //columns for the "where" clause
null, //values fro the "where" clause
null, //columns to group by
null, //columns to filter by row groups
null //sort order
);
// Move the cursor to a valid database row
assertTrue(" Error: No Records returned from location query", c.moveToFirst());
// Validate data in resulting Cursor with the original ContentValues
// (you can use the validateCurrentRecord function in TestUtilities to validate the
// query if you like)
TestUtilities.validateCurrentRecord("Error: location query validation failed", c, locationValues);
//Move the cursor to demonstrate that there is only one record in the database
assertFalse("Error: More than one record returned from location query", c.moveToNext());
// Finally, close the cursor and database
c.close();
db.close();
}
/*
Students: Here is where you will build code to test that we can insert and query the
database. We've done a lot of work for you. You'll want to look in TestUtilities
where you can use the "createWeatherValues" function. You can
also make use of the validateCurrentRecord function from within TestUtilities.
*/
public void testWeatherTable() {
// First insert the location, and then use the locationRowId to insert
// the weather. Make sure to cover as many failure cases as you can.
long locationRowId = TestUtilities.insertNorthPoleLocationValues(mContext);
// Make sure we have a valid row ID.
assertFalse("Error: Location Not Inserted Correctly", locationRowId == -1L);
// Instead of rewriting all of the code we've already written in testLocationTable
// we can move this code to insertLocation and then call insertLocation from both
// tests. Why move it? We need the code to return the ID of the inserted location
// and our testLocationTable can only return void because it's a test.
// First step: Get reference to writable database
SQLiteDatabase db = new WeatherDbHelper(this.mContext)
.getWritableDatabase();
// Create ContentValues of what you want to insert
// (you can use the createWeatherValues TestUtilities function if you wish)
ContentValues contentValues = TestUtilities.createWeatherValues(locationRowId);
// Insert ContentValues into database and get a row ID back
long weatherRowId = db.insert(WeatherContract.WeatherEntry.TABLE_NAME, null, contentValues);
assertTrue(weatherRowId != -1);
// Query the database and receive a Cursor back
Cursor cursor = db.query(WeatherContract.WeatherEntry.TABLE_NAME,
null,
null,
null,
null,
null,
null
);
// Move the cursor to a valid database row
assertTrue("Error: No Records Returned from Weather Query", cursor.moveToFirst());
// Validate data in resulting Cursor with the original ContentValues
// (you can use the validateCurrentRecord function in TestUtilities to validate the
// query if you like)
TestUtilities.validateCurrentRecord("Error: weather query validation failed", cursor, contentValues);
// Move the cursor to demonstrate that there is only one record in the database
assertFalse( "Error: More than one record returned from weather query",
cursor.moveToNext() );
// Finally, close the cursor and database
cursor.close();
db.close();
}
/*
Students: This is a helper method for the testWeatherTable quiz. You can move your
code from testLocationTable to here so that you can call this code from both
testWeatherTable and testLocationTable.
*/
public long insertLocation() {
return -1L;
}
}
Following are the error while testing the TestDb in AndroidTest
LOGCAT:
android.database.sqlite.SQLiteException: near "TABLEweather": syntax error (code 1): , while compiling: CREATE TABLEweather(_idINTEGER PRIMARY KEY AUTOINCREMENT,location_idINTEGER NOT NULL,dateINTEGER NOT NULL,short_descTEXT NOT NULL,weather_idINTEGER NOT NULL,minREAL NOT NULL,maxREAL NOT NULL,humidityREAL NOT NULL,pressureREAL NOT NULL,windREAL NOT NULL,degreesREAL NOT NULL,FOREIGN KEY(location_id)REFERENCES location(_id),UNIQUE (date,location_id) ON CONFLICT REPLACE);
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1674)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1605)
at com.example.admin.sunshine.app.data.WeatherDbHelper.onCreate(WeatherDbHelper.java:50)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:251)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:163)
at com.example.admin.sunshine.app.data.TestUtilities.insertNorthPoleLocationValues(TestUtilities.java:90)
at com.example.admin.sunshine.app.data.TestDb.testWeatherTable(TestDb.java:155)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:191)
at android.test.AndroidTestRunner.runTest(AndroidTestRunner.java:176)
at android.test.InstrumentationTestRunner.onStart(InstrumentationTestRunner.java:555)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1837)
You need to put some "spaces" in your Create table scripts especially in the places where you open/close your doublequotes ("). Below I tried to put an empty space in every doublequote, you can check if it is ok or I missed anything.
final String SQL_CREATE_WEATHER_TABLE="CREATE TABLE " + WeatherContract.WeatherEntry.TABLE_NAME+" ( "+
WeatherContract.WeatherEntry._ID +" INTEGER PRIMARY KEY AUTOINCREMENT, "+
WeatherContract.WeatherEntry.COLUMN_LOC_KEY +" INTEGER NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_DATE +" INTEGER NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_SHORT_DESC +" TEXT NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_WEATHER_ID +" INTEGER NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_MIN_TEMP +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_MAX_TEMP +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_HUMIDITY +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_PRESSURE +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_WIND_SPEED +" REAL NOT NULL, "+
WeatherContract.WeatherEntry.COLUMN_DEGREES +" REAL NOT NULL, "+
" FOREIGN KEY( "+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY +" ) REFERENCES "+
WeatherContract.LocationEntry.TABLE_NAME +" ("+ WeatherContract.LocationEntry._ID+" ), "+
" UNIQUE ( "+ WeatherContract.WeatherEntry.COLUMN_DATE+" , "+ WeatherContract.WeatherEntry.COLUMN_LOC_KEY+
" ) ON CONFLICT REPLACE);";
I'm trying to start with SQLite in android but I have some problems..
I took the code from a tutorial which was written in 2012, but it's not working for me now and shows me this error:
E/SQLiteLog﹕ (1) near "Table": syntax error
The problem is with creating/opening the Database.
package db.com.example.kids1.databasetest;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import org.w3c.dom.Text;
import java.io.IOException;
import java.util.ArrayList;
public class MainActivity extends ListActivity{
private final String DB_NAME = "Database";
private final String TABLE_NAME = "Table";
SQLiteDatabase DB = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayList<String> results = new ArrayList<>();
String[] res = {"Red", "Green", "Text"};
try {
DB = this.openOrCreateDatabase(DB_NAME, MODE_PRIVATE, null);
DB.execSQL("CREATE TABLE IF NOT EXISTS " +
TABLE_NAME +
"(Name VARCHAR, Street VARCHAR, Block INT, City VARCHAR, Tel VARCHAR);");
mFillDbsTable();
Cursor c = DB.rawQuery("SELECT Name, Street, Block, City, Tel FROM " +
TABLE_NAME +
" where Blcok == 9 LIMIT 5", null);
if (c!=null){
if (c.moveToFirst()) {
do {
String name = c.getString(c.getColumnIndex("Name"));
String street = c.getString(c.getColumnIndex("Street"));
int block = c.getInt(c.getColumnIndex("Block"));
String city = c.getString(c.getColumnIndex("City"));
String tel = c.getString(c.getColumnIndex("Tel"));
results.add(name + "," + street + "," + block + "," + city + "," + tel);
} while (c.moveToNext());
}
}
ListView list = (ListView)findViewById(android.R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, res);
list.setAdapter(adapter);
} catch (SQLiteException se){
Log.e(getClass().getSimpleName(), "Create/Open Database Problem.");
}
}
private void mFillDbsTable(){
try {
DB.execSQL("INSERT INTO " +
TABLE_NAME +
" Values('Noam', 'Shkolnik', 9, 'Rehovot', '054-4900807');");
DB.execSQL("INSERT INTO " +
TABLE_NAME +
" Values('Eyal', 'Shkolnik', 9, 'Rehovot', '055-4488779');");
DB.execSQL("INSERT INTO " +
TABLE_NAME +
" Values('Yehontan', 'Shkolnik', 9, 'Rehovot', '058-7789547');");
} catch (SQLiteException se) {
Log.e(getClass().getSimpleName(), "Could not create records.");
}
}
}
private final String TABLE_NAME = "Table"
You can't create a table named Table, because it's a reserved keyword.
You better create a table named MyTable (or _Table or better give a more talkative name, such as Persons - note the s for plurals).
So:
private final String TABLE_NAME = "MyTable"
For your reference: https://sqlite.org/lang_keywords.html
You could (but it's not recommended) use reserved keywords, but then you have to use special delimiters everytime you refer to that table.
Something like
private final String TABLE_NAME = "[Table]"
And there's also another (double) error in your query:
" where Blcok == 9 LIMIT 5"
Should be
" where Block = 9 LIMIT 5"
Try VARCHAR(100) and remove the trailing ;
You got couple of errors. First, do not name your table Table. Table is reserved word (see docs) and cannot be used directly. It's basically not recommended to use reserved words, so I suggest you change your table name, yet if you insist of using it, you need to quote it first:
If you want to use a keyword as a name, you need to quote it. There are four ways of quoting keywords in SQLite:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A
keyword enclosed in square brackets is an identifier. This is not
standard SQL. This quoting mechanism is used by MS Access and SQL
Server and is included in SQLite for compatibility.
keyword A
keyword enclosed in grave accents (ASCII code 96) is an identifier.
This is not standard SQL. This quoting mechanism is used by MySQL and
is included in SQLite for compatibility.
BTW: your further select query will fail too due to typo in where clause:
where Blcok == 9
I'm testing SQLite database in android for the first time.
My program stops as I open it, and i cannot check it, i was wondering if there is a mistake in my code, or database connection,
any help will be appreciated :)
this is my Main.java file:
package de.blattsoft.SQLite;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.Menu;
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SQLiteDatabase db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
Cursor c = db.rawQuery("SELECT * FROM MyTable", null);
c.moveToFirst();
Log.d("Ali", c.getString(c.getColumnIndex("FirstName")));
db.close();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Note: I have asked this question many times ago, and I have written the full answer of how to implement databases in Android in the answers bellow.
First of all you need to create a database, then insert some data in it an then try to display.
What you are doing is ,if database is not there then create and select the column and display. It will obviously fail and your app crash.
Do something like
public void onCreate(SQLiteDatabase db) {
/*CREATE LOGIN TABLE*/
String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "("
+ KEY_ID + " INTEGER PRIMARY KEY,"
+ KEY_NAME + " TEXT," + ")";
db.execSQL(CREATE_LOGIN_TABLE);
}
Then do this ,
public void addMessage(String id, String name){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_ID, id); //
values.put(KEY_NAME, name);
db.insert(TABLE_NAME, null, values);
db.close(); // Closing database connection
}
Then you can display ,
You haven't created the database. And inserting or fetching values from the structure which doesn't exist will lead to crash your app. It's like climbing a building which doesn't exist.
So, first create the database then do rest of the things.
For better understanding follow the you tube video tutorial of Slidenerd. They have sequentially explained all the things for beginners here.
Hope it will help.
I have asked this question many times ago when I was an Android noob! :D
right now this is the way I recommend you to use android sqlite database using helper classes.
as an overview, we need to create two classes, DatabaseHelper class
and DataSource class.
What we need to create:
The DatabaseHelper class must extend SQLiteOpenHelper which is a built-in Android class from android.database.sqlite package and its purpose is to manage database creation and version management.
The DataSource class uses our helper class to implement methods which you need for your application.
For Example, we're going to create a database which has one table called users, and the table has 2 columns: id and name;
The id is going to be used as the primary key.
So, let's create the helper class:
DatabaseHelper.java:
package com.mpandg.android.dbtest;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
// this tag is used for logging purposes.
public static final String TAG = "database";
// database version.
public static final int DATABASE_VERSION = 1;
// database file name.
public static final String DATABASE_NAME = "database.db";
// table details:
public static final String TABLE_USERS = "users";
public static final String USERS_COLUMN_ID = "id";
public static final String USERS_COLUMN_NAME = "name";
// query of creating users table.
public static final String CREATE_USERS_TABLE =
"CREATE TABLE " + TABLE_USERS + " (" +
USERS_COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
USERS_COLUMN_NAME + " TEXT" + ")";
// query string of deleting users table.
public static final String DELETE_TABLES =
"DROP TABLE IF EXISTS " + TABLE_USERS + ";";
// constructor method which takes the context and passes it
// to appropriate super method with other database details
// which creates the database.
public DatabaseHelper(Context context) {
// creates the database using given information.
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// this line executes the query we made earlier
// to create the users table.
db.execSQL(CREATE_USERS_TABLE);
// log the table creation for debugging.
Log.i(TAG, TABLE_USERS + " has been created.");
}
// whenever you give a new update for your application,
// if you change the version of the database, this method
// will be called, you can do your own complicated operations
// on your tables if you need, but right now, I just delete
// the old table and I make an explicit call to onCreate
// method to create the tables again.
// but never forget that you should never make explicit
// calls to onCreate method, but this is an exception here.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// execute the delete query we made earlier.
db.execSQL(DELETE_TABLES);
// explicit call to onCreate. (read the comment above method)
onCreate(db);
}
}
As you see, we have actually created a subclass of SQLiteOpenHelper and we have implemented onCreate(SQLiteDatabase) and onUpgrade(SQLiteDatabase, int, int) methods, and the helper class we created, takes care of opening the database if it exists, creating it if it does not exist and upgrading it if it's necessary.
Now it's time to use the helper class we created and write our methods to use the database in DataSource class.
We will create a database object and we will instantiate it using the methods in our helper class, and we create methods to insert, select and delete.
So, Let's create DataSource.java:
package com.mpandg.android.dbtest;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class DataSource {
// create an instance of SQLiteOpenHelper
// but we're going to instantiate it using
// the helper class we created earlier.
SQLiteOpenHelper dbHelper;
// the main database object which will be
// instantiated using the helper class methods.
SQLiteDatabase dataBase;
private final String TAG = "dataSource";
// an string array holding our table's column names
// which is going to be used by database methods.
public static final String[] usersTableColumns = {
DatabaseHelper.USERS_COLUMN_ID,
DatabaseHelper.USERS_COLUMN_NAME
};
// constructor which receives the activity context.
public DataSource(Context context){
// instantiate the dbHelper object using our DatabaseHelper class.
dbHelper = new DatabaseHelper(context);
}
public void open(){
// opening the database or
// creating the table structures for the first time.
// the helper class knows when to open or create the database.
dataBase = dbHelper.getWritableDatabase();
// log the event for debugging purposes.
Log.i(TAG, "database opened");
}
public boolean isOpen () {
// check if the database is already open.
return dataBase.isOpen();
}
public void close(){
// close the database.
dataBase.close();
// log the event for debugging purposes.
Log.i(TAG, "database closed");
}
// insert a name record into database .
public void insertName (String name) {
// ContentValues implements a map interface.
ContentValues values = new ContentValues();
// put the data you want to insert into database.
values.put(DatabaseHelper.USERS_COLUMN_NAME, name);
// passing the string array which we created earlier
// and the contentValues which includes the values
// into the insert method, inserts the values corresponding
// to column names and returns the id of the inserted row.
long insertId = dataBase.insert(DatabaseHelper.TABLE_USERS , null, values);
// log the insert id for debugging purposes.
Log.i(TAG, "added name id:" + insertId);
}
// returns a list of string
// containing the names saved in the database.
public List<String> getNames (){
List<String> names;
// creating the cursor to retrieve data.
// cursor will contain the data when the
// query is executed.
Cursor cursor = dataBase.query(DatabaseHelper.TABLE_USERS, usersTableColumns,
null, null, null, null, null);
// log the number of returned rows for debug.
Log.i(TAG, "returned: " + cursor.getCount() + " name rows .");
// check if the cursor is not null.
if(cursor.getCount()>0){
// instantiate the list.
names = new ArrayList<>();
// cursor starts from -1 index, so we should call
// moveToNext method to iterate over the data it contains.
while (cursor.moveToNext()) {
// read the string in the cursor row using the index which is the column name.
String name = cursor.getString(cursor.getColumnIndex(DatabaseHelper.USERS_COLUMN_NAME));
// log the retrieved name.
Log.i(TAG, "name retrieved:" + name);
// now add the retrieved name into the list.
names.add(name);
}
// now we have the names in our string list
return names;
} else {
// if the cursor was empty, it means that
// there was no name found in the table,
// so return null.
return null;
}
}
// returns a name corresponding to given id.
public String findNameById (long id){
String name;
// the where clause which is our condition.
String whereClause = DatabaseHelper.USERS_COLUMN_ID + " = ?";
// the arguments passed to
// the where clause. (here is only one argument)
String[] whereArgs = {id+""};
// creating the cursor to retrieve data.
// cursor will contain the data when the
// query is executed.
Cursor cursor = dataBase.query(DatabaseHelper.TABLE_USERS, usersTableColumns,
whereClause, whereArgs, null, null, null);
// log the number of returned rows for debug.
// (logically it should return one row here)
Log.i(TAG, "returned: " + cursor.getCount() + " name rows .");
// check if the cursor is not null.
if(cursor.getCount()>0){
// cursor starts from -1 index, so we should call
// moveToNext method to iterate over the data it contains.
cursor.moveToNext();
// read the string in the cursor row using the index which is the column name.
name = cursor.getString(cursor.getColumnIndex(DatabaseHelper.USERS_COLUMN_NAME));
// log the retrieved name.
Log.i(TAG, "name retrieved:" + name);
return name;
} else {
// if the cursor was empty, it means that
// there was no name found with given id,
// so return null.
return null;
}
}
// delete a name from the table.
public void deleteName (String name) {
// where statement of our delete method.
String whereClause = DatabaseHelper.USERS_COLUMN_NAME + "=" + "?";
// the arguments passed to
// the where clause. (here is only one argument)
String[] whereArgs = {name};
// execute the delete query with delete method.
int deleteId = dataBase.delete(DatabaseHelper.TABLE_USERS , whereClause, whereArgs);
// log the id of the deleted row.
Log.i(TAG, "deleted name id:" + deleteId);
}
}
Now that we have done writing the necessary classes to create and use our database in an appropriate way, it's time to use the methods we wrote in our DataSource class.
All you have to do, is to create an object of DataSource class in your activity and use the methods in it.
when you are intending to use the database, you should open it, you can simply do it by the open() method we wrote in our DataSource class, and after you are done, you must close it to avoid leaks; you can close it using the close() method in 'DataSource` class.
For example, you have some users and you want to add them in the database:
// create the dataSource object
// "this" refers to the activity.
DataSource dataSource = new DataSource(this);
// open the dataBase
dataSource.open();
// insert the names.
dataSource.insertName("Amy");
dataSource.insertName("Johnny");
dataSource.insertName("Abbey");
dataSource.insertName("Miley");
// close the database.
dataSource.close();
Or you want to log all the users in the database:
//TAG for debug logs.
String TAG = "db log";
// create the dataSource object
// "this" refers to the activity.
DataSource dataSource = new DataSource(this);
// open the dataBase
dataSource.open();
// get the names.
List<String> names = dataSource.getNames();
// log all the names in the list.
for (String name: names) {
Log.i(TAG, "retrieved name:" + name);
}
// close the database.
dataSource.close();
Or you want to find a name by its id:
//TAG for debug logs.
String TAG = "db log";
// create the dataSource object
// "this" refers to the activity.
DataSource dataSource = new DataSource(this);
// open the dataBase
dataSource.open();
// find the name by id.
String name = dataSource.findNameById(1);
// log the retrieved name wit id:1.
Log.i(TAG, "retrieved name:" + name);
// close the database.
dataSource.close();
Finally if you want to delete a name:
// create the dataSource object
// "this" refers to the activity.
DataSource dataSource = new DataSource(this);
// open the dataBase
dataSource.open();
// delete the given name
dataSource.deleteName("Amy");
// close the database.
dataSource.close();
That's it.
This is a basic structure for creating databases in Android, as you can see, you can add other tables and columns, easily by adding your own code to the helper class and your own methods to use them in the DataSource class.
Try this
package ir.itstuff.SQLite;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.Menu;
public class Main extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
(EditText) fName = (EditText)findViewById(R.id.editText1);
(EditText) sName = (EditText)findViewById(R.id.editText2);
(Button) save = (Button)findViewById(R.id.button1);
SQLiteDatabase db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS MyTable(id INTEGER PRIMARY KEY AUTOINCREMENT, FirstName varchar,SecondName varchar);")
//Inserting data from inputs
save.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String first_name = fName.getText().toString();
String second_name = sName.getText().toString();
String insert_data="INSERT INTO MyTable (FirstName,SecondName) VALUES " + "('" + first_name + "'," + "'" + second_name + "'" + ")";
shoppingListDB.execSQL(insert_data);
Toast.makeText(getBaseContext(), "Data Inserted", Toast.LENGTH_LONG).show();
Cursor cr=shoppingListDB.rawQuery("SELECT * FROM MyTable;", null);
if (cr.moveToFirst()){
do{
String name = cr.getString(cr.getColumnIndex("FirstName"));
}
while (cr.moveToNext());
Toast.makeText(getBaseContext(), name, Toast.LENGTH_LONG).show;
}
cr.close();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
below is my code i just want to display the data i inserted in the sqlite database to a text view but i have this error saying that the id is not unique.
package com.example.sqlitetest;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
public class Main extends Activity {
TextView scrName, fName;
Button go;
SQLiteDatabase db;
String screenName, fullName;
Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
db = openOrCreateDatabase("MyDataBase", MODE_PRIVATE, null);
db.execSQL("CREATE TABLE if not exists MyTable(ScreenName Varchar, FullName Varchar, id int(3) PRIMARY KEY);");
db.execSQL("Insert into MyTable VALUES('joff', 'tiquez', 1);");
cursor = db.rawQuery("Select * from MyTable", null);
cursor.moveToFirst();
scrName = (TextView) findViewById(R.id.scrName);
fName = (TextView) findViewById(R.id.fName);
while(cursor.isAfterLast() == false){
//retrieving the data from sqlite (im not sure if im doing it right)
String screenname = cursor.getString(cursor.getColumnIndex("ScreenName"));
String fullname = cursor.getString(cursor.getColumnIndex("FullName"));
//this are the textview
scrName.setText(screenname);
fName.setText(fullname);
cursor.moveToNext();
}
db.close();
}
}
this is my whole java code. thanks :)
Well I think this project works fine when you run it first time. When you run it second time it gives error because id is your primary key and the row with the id 1 has been already inserted to your database.
To get rid of errors either :
1) uninstall the app and run it again
2) Don't make id as primary key
3) Catch the exception and handle it yourself
Might I suggest an alternative to this. What you can do is make the id column autoincrement as well while still keeping that column as primary key
EDIT:-
Also I have some other suggestions for you:-
db.execSQL("Insert into MyTable VALUES('joff', 'tiquez', 1);");
you can user ContentValues instead
while(cursor.isAfterLast() == false){
could be replaced with while(!cursor.isAfterLast()){. Looks cleaner this way.
Or you could directly replace while(cursor.isAfterLast() == false){ with while(cursor.moveToNext()){ and can remove out cursor.moveToNext(); from the while block.
Happy Coding!!!
I have written a code that get information from json file related to specific YouTube video and then stores the information I need in my database.
The parsing from json file has no problem. when I am trying to insert values in my database an error message appears telling me that no such table exists.
Here is the stack-trace:
07-31 08:42:22.451: I/Database(365): sqlite returned: error code = 1,
msg = no such table: youtube_VIDEOS 07-31 08:42:22.471: E/Database(365):
Error inserting video_CommentCount=70 video_CountView=50 video_Name=Badly
Drawn Boy - Disillusion (directed by Garth Jennings)
video_Url=https://www.youtube.com/watch?v=B11msns6wPU&feature=youtube_gdata_player
video_LIKES=60 video_Img=https://i1.ytimg.com/vi/B11msns6wPU/default.jpg
video_Descrption=My new playlist Description 07-31 08:42:22.471:
E/Database(365): android.database.sqlite.SQLiteException:
no such table: youtube_VIDEOS: ,
while compiling: INSERT INTO youtube_VIDEOS(video_CommentCount, video_CountView, video_Name, video_Url,video_LIKES, video_Img, video_Descrption) VALUES(?, ?, ?, ?, ?, ?, ?);
07-31 08:42:22.471: E/Database(365): at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
And here is my database code:
package com.example.tstnetconnwithjson.db;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class youtube_db extends SQLiteOpenHelper {
public static final String dataBase_NAME="YOUTUBE_database";
private static final int dataBase_VERSION=1;
private static final String dataBase_TABLE="youtube_VIDEOS";
public static final String[] COLS_List={"video_Name","video_Descrption","video_Img","video_Url","video_CountView","video_LIKES","video_CommentCount"};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//end of declaring attributes and tables conents
public youtube_db(Context context) {
super(context,dataBase_NAME, null, dataBase_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(
"create table" + dataBase_NAME + "(" + COLS_List[0] +" text not null , "+ COLS_List[1]
+" text not null , "+ COLS_List[2]+" text not null , "+COLS_List[3]+" text not null , "+COLS_List[4]+" integer , "+COLS_List[5]
+" integer , "+COLS_List[6]+" integer ) ");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.i("in the upgrade", "ok");
}
}
And here is the function that would insert the information in my database:
package com.example.tstnetconnwithjson.db;
import com.example.tstnetconnwithjson.tables.videos;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class youtubeDataBaseManager {
SQLiteDatabase SQL_db;
youtube_db my_Database;
public youtubeDataBaseManager(Context c){
my_Database=new youtube_db(c);
SQL_db= my_Database.getWritableDatabase();
}//end of costructor
public long insert_Youtube_Info( videos video){
ContentValues contentValues = new ContentValues();
contentValues.put(youtube_db.COLS_List[0], video.getVideoname());
contentValues.put(youtube_db.COLS_List[1], video.getDecscrption());
contentValues.put(youtube_db.COLS_List[2], video.getImageurl());
contentValues.put(youtube_db.COLS_List[3], video.getVediourl());
contentValues.put(youtube_db.COLS_List[4], "50");
contentValues.put(youtube_db.COLS_List[5], "60");
contentValues.put(youtube_db.COLS_List[6], "70");
long addResult ;
addResult= SQL_db.insert(youtube_db.dataBase_TABLE, null, contentValues);
if(addResult==-1)
{
Log.i("add video", "add error.... ");
}
else
{
Log.i("add video", "add:ok.... ");
}
return addResult;
}
Can anyone tell me what is the problem?
"create table" + dataBase_NAME + "("
You are missing space between name and <create table> keyword. You have to change it to:
"create table " + dataBase_TABLE + "("
Otherwise, your DDL statement won't work.
Later, you try and reference a table called "youtube_VIDEOS", which doesn't exist. Because you never created it. It's all about typo.
you should change here:
create table" + dataBase_TABLE+ "(" + COLS_List[0] +" text not null , "+ COLS_List[1]
+" text not null , "+ COLS_List[2]+" text not null , "+COLS_List[3]+" text not null , "+COLS_List[4]+" integer , "+COLS_List[5]
+" integer , "+COLS_List[6]+" integer ) ");
You have that error, because your table in database didn't successfully created. Why ? Because your table hasn't got primary key (id). Add, e.g :
`_id` INT PRIMARY KEY AUTOINCREMENT,
And now every thing should work correctly