SQLiteDatabase.insert() and SQLiteDatabase.execSQL("insert into ...") doesn't work - java

I'm working on an Android application in Java. In my application I need, among other things, to store an address in a database. My address is stored in a table named "adresse". This table is defined as below:
CREATE TABLE "adresse" (
"numero_rue" TEXT,
"type_voie" TEXT,
"voie" TEXT,
"code_postal" TEXT,
"ville" TEXT
);
I've tried to insert an address in my table by two different methods:
public void setAdresse(String numRue, String typeVoie, String voie, String codePostal, String ville) {
// First one
ContentValues values = new ContentValues();
values.put("numero_rue" , numRue );
values.put("type_voie" , typeVoie );
values.put("voie" , voie );
values.put("code_postal", codePostal);
values.put("ville" , ville );
db.insert("adresse", null, values);
// Second one
String req = "insert into adresse (numero_rue, type_voie, voie, code_postal, ville) values";
req += "(\"" + numRue + "\",\"" + typeVoie + "\",\"" + voie + "\",\"" + codePostal + "\",\"" + ville + "\")";
db.execSQL(req);
}
I call the setAdresse(...) method in this method:
public void valider(View paramView) {
[ data recovery without problems ]
final DatabaseAccess db = DatabaseAccess.getInstance(this.getApplicationContext());
db.open();
db.setAdresse(numRue, typeVoie, voie, codePostal, ville);
db.close();
}
I show you my constructor, my open(), close() and getInstance() methods:
private DatabaseAccess(Context context) { this.openHelper = new DatabaseOpenHelper(context); }
public static DatabaseAccess getInstance(Context context) {
if( instance == null ) instance = new DatabaseAccess(context);
return instance;
}
public void open() { this.db = openHelper.getWritableDatabase(); }
public void close() { if( this.db != null ) this.db.close(); }
My problem is that inserting the data into the table is not working. I don't find errors in the logs and my application does not crash. I don't think it is a code error and someone told me it could be linked to my "driver utilisation".

can you check this link. It is a github sample project for inserting in sqlite table

Related

Null Pointer Exception in Android Content Provider [duplicate]

Im trying to store a particular columns data in a method and call that method in another classes String [] where a spinner will access that array to display the columns rows for the user to select which will then get stored in another database.
Im getting nulpointerexception and when I try and open() the database the database gets locked. Sorry for sounding like a complete amateur, relatively new to android. Thank you in advance for any help.
Here is my code when I call getInstance() and getCPnames() in my main class
String[] carParks = CarParkDb.getInstance().getCpnames();
Here is my code for the database:
package com.example.parkangel;
import java.util.ArrayList;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class CarParkDb {
public static final String KEY_ID = "_id";
public static final String KEY_CPNAME = "cpname";
public static final String KEY_COST = "cost";
private static final String DATABASE_NAME = "CPDB";
private static final String DATABASE_TABLE = "CPTable";
private static final int DATABASE_VERSION = 1;
private CPDbHelper cpdbHelper;
private Context ourContext;
private SQLiteDatabase ourDatabase;
private static CarParkDb instance;
private static class CPDbHelper extends SQLiteOpenHelper{
public CPDbHelper(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_TABLE + " (" +
KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_CPNAME + " TEXT NOT NULL, " + KEY_COST + " TEXTNOT NULL);");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('1','LearningResource Center','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('2','ParkandRide','1');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values ('3','deHavilland Campus','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('4','MultiStorey Building','2');");
db.execSQL("INSERT INTO " + DATABASE_TABLE + " Values('5','Reception','2');");
}
public void onOpen(final SQLiteDatabase db) {
super.onOpen(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
public CarParkDb (final Context c)
{
this.cpdbHelper= new CPDbHelper(c);
establishDb();
//ourContext = c;
}
public void establishDb()
{
if (this.ourDatabase == null)
{
this.ourDatabase = this.cpdbHelper.getWritableDatabase();
}
}
public CarParkDb() {
// TODO Auto-generated constructor stub
}
public CarParkDb open() throws SQLException
{
System.out.println ("running open");
cpdbHelper = new CPDbHelper(ourContext);
ourDatabase = cpdbHelper.getWritableDatabase();
return this;
}
public void close()
{
ourDatabase.close();
}
/*public long createEntry(String cpname, String cost){
ContentValues cv = new ContentValues();
cv.put(KEY_CPNAME, cpname);
cv.put(KEY_COST, cost);
return ourDatabase.insert(DATABASE_TABLE, null, cv);
}*/
public String getData() {
// TODO Auto-generated method stub
//open();
String[] columns = new String[] {KEY_ID, KEY_CPNAME, KEY_COST};
Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null,null,null, null, null);
String result = " ";
int iRow = c.getColumnIndexOrThrow(KEY_ID);
int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
int iCost = c.getColumnIndexOrThrow(KEY_COST);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
result = result + c.getString(iRow) + " " +c.getString(iCpname) + " " + c.getString(iCost) + " " + "\n";
c.close();
ourDatabase.close();
}
return result;
}
public static CarParkDb getInstance()
{
synchronized(CarParkDb.class)
{
if (instance == null)
{
instance = new CarParkDb();
}
return instance;
}
}
public String[] getCpnames()
{
//open();
if (ourDatabase == null) System.out.println ("is null");
Cursor c = null;
ArrayList<String> list = new ArrayList<String>();
ourDatabase = cpdbHelper.getReadableDatabase();
//SQLiteDatabase db = cpdbHelper.getReadableDatabase();
String query = "SELECT " + KEY_CPNAME + " FROM " + DATABASE_TABLE;
{
c = this.ourDatabase.rawQuery(query, null);
int iCpname = c.getColumnIndexOrThrow(KEY_CPNAME);
if (c.moveToFirst())
{
do
{
list.add(c.getString(iCpname));;
}
while (c.moveToNext());
}
if (c != null && !c.isClosed())
{
c.close();
ourDatabase.close();
}
return list.toArray(new String[]{});
}
}
}
**LogCat**
03-12 01:32:39.759: E/AndroidRuntime(4176): Caused by:java.lang.NullPointerException
03-12 01:32:39.759: E/AndroidRuntime(4176):
at com.example.parkangel.CarParkDb.getCpnames(CarParkDb.java:191)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at com.example.parkangel.BookTicket.<init>(BookTicket.java:22)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at java.lang.Class.newInstanceImpl(Native Method)
03-12 01:32:39.759: E/AndroidRuntime(4176):
at java.lang.Class.newInstance(Class.java:1208)
The database doesn't get locked. The "locked" thinkg is just a NPE in a method called getDatabaseLocked() and it's caused by a null Context passed to SQLiteOpenHelper in constructor that manifests itself with getWritableDatabase() or getReadableDatabase().
To fix the NPE in getDatabaseLocked(), make sure ourContext in open() is not null. As of now, you've never initialized ourContext and it's always null. Uncomment the //ourContext = c; in constructor and move it above the establishDb(), remove the other no-argument constructor and pass in a Context for example as suggested by Merlevede.
The NPE stacktrace in your question is when you call getCpNames() with open() commented out and are trying to call a method on a null ourDatabase object reference. Uncomment the open() there once it's fixed. The stacktrace also says you're trying to call getCpNames() in object initialization phase e.g. when initializing a member variable. That might be too early, for example an activity cannot be used as a Context until onCreate().
Some other things in your code you'd hit next:
in onCreate(): + KEY_COST + " TEXTNOT NULL) - add space between TEXT and NOT
in getData(): you're closing the cursor and database in the loop where you're accessing the cursor. Do it after the loop. The code shouldn't compile as you're not returning anything from a non-void function in case moveToFirst() returns false.
Try updating your getInstance() code with this:
public static CarParkDb getInstance(Context c) // <-- added context as parameter
{
synchronized(CarParkDb.class)
{
if (instance == null)
{
instance = new CarParkDb(c); // <-- used context in constructor
}
return instance;
}
}
The problem seems to be that you're using a constructor (for CarParkDb) that does nothing. You have another constructor that takes a Context as parameter and initializes some of the objects that you're using later.

Android Studio - unable to retreive data from preinstalled sqlite database

EDIT: I still can't find a solution to this issue. For some reason, the database that is queried is empty, despite being full and in the correct place. If you can see any issue with my database helper or anything else that I could try, I would be very grateful.
I am developing an app that returns information from an SQLite database relating to species of bird. When I query this database, I am getting error messages: 'SQLiteLog: (1) no such column: 'size'' etc.
I have verified that my rawQuery() queries are well formed and should be returning the info that I expect by running the queries in an SQLite browser, and by consulting advice on Stackoverflow. I have tried to use the alternative database asset class, SQLiteAssetHelper, but have had the same problems as I have with SQLiteOpenHelper.
I am thinking it may be related to:
the testing phone - Moto g6 play - this phone is not rooted. Could this be an issue migrating the database over to the phone for use by the app during testing?
The formation of the database - this was populated by a python script written by me. Could some metadata etc be malformed or incompatible?
package com.example.newbuild;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
//db info
private static final String DATABASE_NAME = "birdsDB.db";
// FileInputStream fis = new FileInputStream(new File(DATABASE_NAME));
// Log info for debugging:
private static final String TAG = "DatabaseHelper";
// set variables to name database
private static final int DATABASE_VERSION = 3;
// name of table 1:
private static final String MAIN_TABLE = "main";
// name of bird image table:
private static final String PIC_TABLE = "picLinks";
// names of MAIN columns:
private static final String ID = "id";
private static final String COMMON = "common";
private static final String SCINAME = "sciname";
private static final String FAMILY = "family";
private static final String BIRDCATEG = "category";
private static final String SIZE = "size";
private static final String DESC = "description";
private static final String RANGEPIC = "rangepicid";
private static final String SIGHTED = "sighted";
// names of BIRD IMAGE columns
private static final String BIRD_IMAGE_NO = "picKey";
private static final String BIRD_ID = "birdId";
private static final String IMAGE_LINK = "link";
private Context mContext;
private SQLiteDatabase mDB;
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.i(TAG, "now calling database helper");
}
#Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "attempting to create table from onCreate");
String CREATE_MAIN_TABLE =
"CREATE TABLE " +
MAIN_TABLE +
"(" +
ID + "INTEGER PRIMARY KEY," +
COMMON + " TEXT," +
SCINAME + " TEXT," +
FAMILY + "TEXT," +
BIRDCATEG + "TEXT," +
SIZE + "TEXT," +
DESC + "TEXT," +
RANGEPIC + "TEXT," +
SIGHTED + "TEXT" +
")";
db.execSQL(CREATE_MAIN_TABLE);
Log.d("table", CREATE_MAIN_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
Log.i(TAG, "now calling onUpgrade");
db.execSQL("DROP TABLE IF EXISTS " + MAIN_TABLE);
onCreate(db);
}
}
public ArrayList<String> getCategory(String[] name) {
String TABLE_BIRDS = "main";
ArrayList<String> categories = new ArrayList<>();
if (name[0] != null) {
Log.d(LOG_TAG, name[0]);
} else {
Log.d(LOG_TAG, "name[0] has not been passed");
}
Log.d(LOG_TAG, "SELECT DISTINCT " + name[0] + " FROM " + TABLE_BIRDS);
Cursor x = db.rawQuery("SELECT DISTINCT " + name[0] + " FROM " + TABLE_BIRDS, null);
if (x.getCount() == 0) {
Log.i(LOG_TAG, "The cursor is not returning any data");
}
while (x.moveToNext()) {
String category = x.getString(0);
categories.add(category);
Log.i("cursor loop", category);
}
return categories;
}
When the above code is passed the string 'category', my database should return six strings of different categories of bird species. Instead, I find error messages including 'E/SQLiteLog: (1) no such column: category'.
I am thinking it may be related to: the testing phone - Moto g6 play -
this phone is not rooted. Could this be an issue migrating the
database over to the phone for use by the app during testing?
I don't think so as you would typically get a table not found before a column not found.
I'd suggest temporarily changing the query to :-
Cursor x = db.rawQuery("SELECT * FROM " + TABLE_BIRDS + " LIMIT 10", null);
Followed by :-
DatabaseUtils.dumpCursor(x);
The first change will extract all columns from 10 rows from the table.
The second line will output the data in the cursor to the log, including the column names.
I suspect that the column names are incorrect or missing. In which case you need to ensure that the file in the assets folder is correct, when it is make sure that you delete the database (delete the Apps data or uninstall the App) and then rerun the App.

Using sql lite database in another android app

hello i have a problem with android. In my app i get data from a webservice and i read it into a sql lite database . In my activity i have multiple spinners who are filled with data from the DB. After selecting all the spinners and clicking the button i go to an other activty where i click a link and the data is written into another table.
I will explain what the app is like a form where a student can choose with school , study area,.. till you have the tuition you want. You can subscribe than for the course(that data is written to another table).
In the other app you can see the tuition whit the number of subscribers.
the first app works but my problem is that i need the table of subscibers used in app 1 for app2
i have read about COntent providers ,shared user id but none of it works.
Can somebody help me?
public class SchemaHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAAM ="av_helpdesk.be.db";
private static final int DATABASE_VERSIE = 10;
public SchemaHelper(Context context) {
super(context, DATABASE_NAAM, null, DATABASE_VERSIE);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "
+ GegevensTabel.TABEL_NAAM
+ " (" + GegevensTabel.ID
+ " INTEGER PRIMARY KEY,"
+ GegevensTabel.INSTELLING
+ " TEXT,"
+ GegevensTabel.OPLEIDINGSTYPE
+ " TEXT,"
+ GegevensTabel.OPLEIDINGSGEBIED
+ " TEXT,"+ GegevensTabel.OPLEIDING+" TEXT,"
+ GegevensTabel.MODULE+" TEXT,"
+ GegevensTabel.LESPLAATS_ADRES+" TEXT,"
+ GegevensTabel.AAVANGS_DATUM+" TEXT"+");"
);
db.execSQL("CREATE TABLE "
+ InschrijvingTabel.TABEL_NAAM
+ " (" + InschrijvingTabel.ID
+ " INTEGER PRIMARY KEY,"
+ InschrijvingTabel.LESPLAATS
+ " TEXT, "
+ InschrijvingTabel.OPLEIDING
+ " TEXT, "
+ InschrijvingTabel.Module
+ " TEXT, "+ InschrijvingTabel.AANTAL+" INTEGER"+");"
);
}
public interface InschrijvingTabel {
String ID="_id";
String Module = "_module";
String TABEL_NAAM = "TBL_INSCHRIJVING1";
String AANTAL="_aantal";
String OPLEIDING="_opleiding";
String LESPLAATS="_lesplaats";
}
public class InschrijvingDB extends SchemaHelper {
public InschrijvingDB(Context context) {
super(context);
}
public void adVakken()
{
SQLiteDatabase sd=getWritableDatabase();
// String xx=x.getModule();
// sd.rawQuery("insert into "+InschrijvingTabel.TABEL_NAAM+"("+ InschrijvingTabel.Module+") values("+xx+")",null);
// sd.rawQuery("insert into "+InschrijvingTabel.TABEL_NAAM+"(_module) values('cc')",null);
}
public class contentPV extends ContentProvider {
static final String PROVIDER_NAME = "com.example.derae.lessenrooster.databank.contentPV";
static final String URL = "content://" + PROVIDER_NAME + "/*";
static final Uri CONTENT_URI = Uri.parse(URL);
#Override
public boolean onCreate() {
Context context = getContext();
InschrijvingDB x= new InschrijvingDB(context);
return false;
}
#Nullable
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return null;
}
#Nullable
#Override
public String getType(Uri uri) {
return null;
}
#Nullable
#Override
public Uri insert(Uri uri, ContentValues values) {
return null;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return 0;
}
}
If you're using 1 database that has all the tables you want to use and you're logging in to that database from app 2, then you should be able to access every table there.
Try debugging techniques to see what's going wrong with app 2, like print debugging.
If you can connect to your database normally from app2, then check if there's anything wrong with your Queries to get data from the desired table. Break your problem down into parts.
-I'm sorry if this is not helpful enough, I'm no expert myself, but I hope my tips help you discover the problem yourself.

Using method from one class into class

I have two classes:
MyActivity.Java
DatabaseHandler.Java
I would like to take the returning String from the method "getCurrentCar" and put it inside MyActivity.java
DatabaseHandler.Java:
public class DatabaseHandler extends SQLiteOpenHelper {
public Car getCurrentCar() {
SQLiteDatabase db = getWritableDatabase();
String sql = "SELECT " + KEY_ID + "," + KEY_IMAGE + " FROM " + TABLE_CARS + "ORDER BY RANDOM() LIMIT 1";
Cursor cursor = db.rawQuery(sql, new String[] {});
Car car = null;
try {
if (cursor.moveToFirst()) {
car = new Car(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3));
}
}
finally {
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
db.close();
}
return car;
}
}
I have attempted already, but the parameters are asking for Context.
//DatabaseHandler handler = new DatabaseHandler(contexthere);
DatabaseHandler handler = new DatabaseHandler();
handler.getCurrentCar();
I would like to know how to take that return and put it inside my MyActivity.java so I can then use a BitmapFactory to recreate the image.
Thanks
Context means current runtime :
protected void onCreate(Bundle savedInstanceState) {
...........
...........
// you should instantiate 'DatabaseHandler' here
DatabaseHandler db = new DatabaseHandler(this); // "this" refer to the context
..........
..........
// insert the rows
db.createCar(new Car("Sesame street A","23423","anImage1"));
db.createCar(new Car("Sesame street B","43543","anImage2"));
// get the rows which you mean string
for(Car cars : db.getCurrentCar()){
String rows= "id : "+ cars.getID()+ " address : "+getAddress() + "postcode : "+getPostcode()+" image : "+getImage());
}
}
Just adapt .getID(),getAddress(),getPostcode(),getImage() based on the 'getter' methods name in your Car class, as I might write them wrongly
** Codes above I write based on the file that you shared by a link. (your file missing Car class), but I just predict that it should be like above :

How to properly write SQLite update function with string comparison in the where cluse

I have a table with two columns first is date and the second is a counter. I do not have a primary key but the date acts as one. So my code checks if the current date exists in the table, if so it will only increment the counter other wise it will add a new entry. The existence of the current date is only possible at the last row. here is the code:
SQLiteOpenHelper implementation:
public class SqliteHelperInstance extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "app_stats";
public static final String TABLE_NAME = "day_stats";
public static final String COLUMN_DATE = "date";
public static final String COLUMN_CIGCOUNT = "cigcount";
public static final int DATABASE_VERSION = 1;
private static final String CREATE_DB = "create table " + TABLE_NAME + " ( " + COLUMN_DATE + " text, "
+ COLUMN_CIGCOUNT + " integer );";
public SqliteHelperInstance(Context context){
super(context,DATABASE_NAME , null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(CREATE_DB);
}
}
The implementation of database manager:
public class DbManager {
private SqliteHelperInstance sqlHelper;
private SQLiteDatabase database;
private String[] columns = { SqliteHelperInstance.COLUMN_DATE, SqliteHelperInstance.COLUMN_CIGCOUNT};
public DbManager(Context context){
sqlHelper = new SqliteHelperInstance(context);
}
public void addEntry(Calendar cal){
ContentValues values = new ContentValues();
String dateEntry = dateFormatter(cal);
Cursor cursor = database.query(SqliteHelperInstance.TABLE_NAME, null, null, null, null, null,
SqliteHelperInstance.COLUMN_DATE + " DESC LIMIT 1");
//check if the last entered date is equal to the current date
if(cursor.moveToFirst()){
String lastDate = cursor.getString(0);
if(lastDate.equalsIgnoreCase(dateEntry)){
//the cigNum should be updated for the current date
int cigNum = cursor.getInt(1);
cigNum ++;
values.put(SqliteHelperInstance.COLUMN_DATE,lastDate);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, cigNum);
int i = database.update(SqliteHelperInstance.TABLE_NAME, values,SqliteHelperInstance.COLUMN_DATE + " = " + lastDate , null);
if(i == 0){
Log.d("Tag", "No row is affected");
}
}
else{
//the last date is different than current day so we need to add a new entry
DbEntry newEntry = new DbEntry();
newEntry.setDate(dateEntry);
values.put(SqliteHelperInstance.COLUMN_DATE, dateEntry);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, newEntry.getCigNum());
database.insert(SqliteHelperInstance.TABLE_NAME, null, values);
}
}
else{
//its the first time that the application is loading
DbEntry newEntry = new DbEntry();
newEntry.setDate(dateEntry);
newEntry.setCignum(1);
values.put(SqliteHelperInstance.COLUMN_DATE, dateEntry);
values.put(SqliteHelperInstance.COLUMN_CIGCOUNT, newEntry.getCigNum());
Log.i(null, "values are set");
database.insert(SqliteHelperInstance.TABLE_NAME, null, values);
}
}
But when I run the application, I keep getting 0 row affected by the update function.I assume the comparison in the where clause is not returning any particular row. can anyone help me with this issue?
Try getting the lastDate like this:
String lastDate = cursor.getString(cursor.getColumnIndex(SqliteHelperInstance.COLUMN_DATE));
Also, you should use parameterized queries:
int i = database.update(SqliteHelperInstance.TABLE_NAME, values,SqliteHelperInstance.COLUMN_DATE + " = ?", new String[]{ lastDate });
Other than that, I'm not sure what could be wrong.

Categories

Resources