I have an app that allows the user to save some chosen rows from a temporary table. The user is able to name the new table.
I am successfully creating a table using the name the user has input, and putting all the chosen rows from the temporary table into the new table.
However, if the table name they enter already exists, I want to notify them via Toast and have them choose another name. I am still learning sqlite - is there a way to do this?
In my head I am using some sort of if statement to check if the table exists, and then executing code, however half of it is in sqlite and half is in java. I'm not sure the correct way to do this. Any suggestions are greatly appreciated!
private void createTable() {
dbHandler.getWritableDatabase().execSQL("CREATE TABLE IF NOT EXISTS " + favoriteName + " ( _id INTEGER PRIMARY KEY AUTOINCREMENT , exercise TEXT , bodypart TEXT , equip TEXT );");
dbHandler.getWritableDatabase().execSQL("INSERT INTO " + favoriteName + " SELECT * FROM randomlypicked");
Try
Cursor cursor = dbHandler.getReadableDatabase().rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName +"'", null);
if(cursor!=null) {
if(cursor.getCount()>0) { //table already exists
//show toast
cursor.close();
return;
}
cursor.close();
}
//create table and insert normally
Related
I am adding a new column to an existing table and adding a new entry to the table with valid data present only in new column (other column being 0 by default)
Adding Column :
final String DB_ADD_COLUMN_STATEMENT_TABLE_SHOP_NAME =
"ALTER TABLE "+ shopName + " ADD COLUMN "+ "D" + time + " FLOAT";
try {
mDB.beginTransaction();
//SQLiteStatement statement = mDB.compileStatement(DB_ADD_COLUMN_STATEMENT_TABLE_SHOP_NAME);
//statement.execute();
mDB.execSQL(DB_ADD_COLUMN_STATEMENT_TABLE_SHOP_NAME);
mDB.setTransactionSuccessful();
}
catch (Exception e) {
Log.d(LOG_TAG,"addItemSample : Exception while adding column to table!!");
}
finally {
mDB.endTransaction();
}
Adding a new entry to the table with data only in this column succeeds.
But when I query the table , this new column doesn't show up in the cursor.
Though the adding column and querying happen in different threads, they are serialized from the way they are being called from my code (ie first column is added and then db is queried) and also the I am using a single connection to db.
I wondering what might be reason for this?
PS:When db query is performed immediately after inserting the column , it shows up.
depends on your query statement.
is it like
String query="select id, column1, column 2 from "+shopName+" where yourcondition";
?
may be you have to add column?
String query="select id, column1, column2, D192200 from "+shopName+"";
or you may query all columns
String query="select * from "+shopName+"";
The issue could be that you are adding a column that expects NOT NULL values
Try something like this:
ALTER TABLE "+ shopName + " ADD COLUMN "+ "D" + time + " FLOAT" default 0 NOT NULL;
Use which ever default value you need and update the values as needed.
I have a problem to create a table. If I try to get a value from the second column, android writes a empty space in the toast. But if I try to get a value from the first column, android writes the value of the column correctly. The query functions to write the first column and to write the second column are equal. So I think the Creation of the Table is the problem. But look yourself:
public SQLiteDatabase tabelleerstellen(){
SQLiteDatabase leveldatabase = openOrCreateDatabase("leveldata.db",SQLiteDatabase.CREATE_IF_NECESSARY, null);
leveldatabase.setVersion(1);
final String CREATE_TABLE_LEVEL =
"CREATE TABLE IF NOT EXISTS tbl_level ("
+ "id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ "ME1 TEXT, "
+ "ME2 TEXT, "
+ "ME3 TEXT, "
+ "ME4 TEXT, "
+ "ME5 TEXT, "
+ "ME6 TEXT, "
+ "ME8 TEXT, "
+ "GESCHAFFT INTEGER);";
leveldatabase.execSQL(CREATE_TABLE_LEVEL);
return leveldatabase;
}
public void tester(SQLiteDatabase leveldata){
ContentValues cursortester = new ContentValues();
cursortester.put("ME2","25");
leveldata.insert("tbl_level",null,cursortester);
String[] testerpr = {"ME2"};
Cursor testerprüfen = leveldata.query("tbl_level",testerpr,null,null, null, null,null,null);
testerprüfen.moveToFirst();
String dada = testerprüfen.getString(testerprüfen.getColumnIndex("ME2"));
Toast testertoast = Toast.makeText(getApplicationContext(),dada,Toast.LENGTH_SHORT);
testertoast.show();
}
Please check the following things:
Please make sure the table is up to date .. so try to call DROP TABLE IF EXISTS tbl_level; and recreate the table.
If you run a test make sure the table is completely empty ... so delete everything at the beggining of the test.
If the table can contain elements during the test then make sure you check the last inserted element. Please note that calling testerprüfen.moveToFirst(); moves the cursor to the first row in the table so checking that row every time is even if the table contains 50 elements is not a good thing. In this case you either use a sorting option in your query of uese while (testerprüfen != null && testerprüfen.moveToNext()) {// Your code here}
All in all I think your problem is that you already inserted more that one element in the able but you always check only the first element (with testerprüfen.moveToFirst();). Please not that there is a cursor.moveToLast() method that you can also call. This method moves the cursor to the last row in the table.
I have three tables (Training, Person and attendance). The connection between the table is; Training has its fields same to person. And the attendance table has only two fields training_id and person_id. When person register to the training, the training_id and person_id insert into the attendance table. Ok, I am able to insert new person. When person that was already attended to the training and want to update himself, the table (person) gets updated but in the attendance table, the person is inserted again. What I want is when the person updated himself, the attendance table should not insert him again.
I tried this;
public void registerToTraining(int training_id) {
DatabaseHelper db = DatabaseHelper.getInstance();
String query = "SELECT * FROM attendance WHERE training_id = "
+ Integer.toString(training_id) + " AND person_id = "
+ Integer.toString(this.getId()) + ";";
db.sqlCommand(query);
if(The query does not return one row or more){
String command = "INSERT INTO attendance (training_id , person_id) VALUES ("
+ Integer.toString(training_id)
+ ", "
+ Integer.toString(this.getId()) + ") ;";
db.sqlCommand(command);
}
First Query then database then make the cursor move to first or not .
if(cursor.moveFirst)
{
Aleady exsist data.
}else
{
new data insert
}
You can use a UNIQUE constraint on the columns of the table when creating it and skip the conflicting row when the constraint is violated (http://www.sqlite.org/lang_conflict.html)
CREATE TABLE attendance (training_id INT, person_id INT, UNIQUE(training_id, person_id)
ON CONFLICT IGNORE);
This is my database
db.execSQL("CREATE TABLE " + DATABASE_TABLE + " (" +
KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_CATEGORY + " TEXT NOT NULL, " +
KEY_DATE + " TEXT, " +
KEY_PRICE + " LONG, " +
KEY_DETAILS + " TEXT NOT NULL);"
);
and this is the method for deleting all data
public void deleteall() {
// TODO Auto-generated method stub
ourDatabase.delete(DATABASE_TABLE, null, null);
}
and this is the method for deleting a particular data
public void deletentry(long l) {
// TODO Auto-generated method stub
ourDatabase.delete(DATABASE_TABLE, KEY_ROWID + " = " + l,null);
}
Here using the data I deleted but incremented row-id remains there, which I want to reset to 1 as the data is deleted also if I delete a particular data the row-id changes it's value in a sequence manner there should be no gap in between row-id.
I don't think autoincrement is your best option. If your goal is to create a simple numbered table with no gaps, it may be much easier to handle this using a table with a column for you to manually keep up with your ID's.
If you created a table like that, you could then write helper methods in your code for the following operations: addColumn, removeColumn, emptyTable.
Your addColumn method would query the table and determine the max(ID) then add 1 and use that number for the next entry.
Your removeColumn method could remove the entry by ID, then use that ID to resequence everything above it. Or, if order is not important, it could take the last row and re-id it to fill in the gap.
Your emptyTable method could remove all entries.
Update
Maybe this can get you started. The methods would need to be defined in your program. You would have to put the code inside them and then set them up to be called.
For example:
public void addColumn(String category, long date, String details) {
//code here would need to determine the max of ID and add one
//to it. the sql below would retrieve max, i dont know the sql lite code
//off the top of my head.
//SELECT MAX(ID) FROM DATABASE_TABLE;
int newID = max + 1;
//add row to the database using newID
}
public void removeColumn(int id) {
//remove column from database
//DELETE FROM DATABASE_TABLE WHERE ID = id;
//change last entry to use id
//UPDATE DATABASE_TABLE SET ID = id WHERE id = (SELECT MAX(ID) FROM DATABASE_TABLE);
}
public void emptyTable() {
//DELETE FROM DATABASE_TABLE;
}
To call these methods, you would call them like any other java method in your class:
addColumn(12, 'text', (long)100, 'text');
removeColumn(10);
emptyTable();
SQLite keeps the largest ROWID in the special SQLITE_SEQUENCE table. You can delete that table as:
db.delete("SQLITE_SEQUENCE","NAME = ?",new String[]{TABLE_NAME});
Unfortunately, SQLite AUTOINCREMENT is not guaranteed to work as you want. Quoting the docs:
If no ROWID is specified on the insert, or if the specified ROWID has
a value of NULL, then an appropriate ROWID is created automatically.
The usual algorithm is to give the newly created row a ROWID that is
one larger than the largest ROWID in the table prior to the insert. If
the table is initially empty, then a ROWID of 1 is used. If the
largest ROWID is equal to the largest possible integer
(9223372036854775807) then the database engine starts picking positive
candidate ROWIDs at random until it finds one that is not previously
used. If no unused ROWID can be found after a reasonable number of
attempts, the insert operation fails with an SQLITE_FULL error. If no
negative ROWID values are inserted explicitly, then automatically
generated ROWID values will always be greater than zero.
If you need this specific behaviour you described, the only solution would be for you to manually control the KEY_ROWID for your table, making sure you properly account for inserts and deletes.
You can also delete your table from SQLite_Sequence using
sqlDb.execSQL("DELETE FROM SQLITE_SEQUENCE WHERE NAME = 'YOUR_TABLE_NAME'");
My Create table Query is:--
String CREATE_LOGIN_TABLE ="CREATE TABLE IF NOT EXIST "+ TABLE_FORWARDMSG +"("+KEY_ID+ " INTEGER PRIMARY KEY AUTOINCREMENT,"+KEY_MSG_BODY+ " TEXT UNIQUE,"+KEY_MSG_ADDRESS+" TEXT UNIQUE,"+KEY_MSG_DATE+" TEXT UNIQUE" +")";
and I am access values From This Code:---
String selectQuery="SELECT * FROM "+TABLE_FORWARDMSG;
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.rawQuery(selectQuery, null);
if( cursor.moveToFirst()){
for(int i=0;i<cursor.getCount();i++){
map.put("msgBody", cursor.getString(1));
map.put("msgAddress", cursor.getString(2));
map.put("msgDate", cursor.getString(3));
user.add(map);
cursor.moveToNext();
}
}
cursor.close();
db.close();
Now My Problem is that:----
If I remove UNIQUE from the CREATE TABLE Then I get all duplicate values means if I insert same value it create new row, and if I am using UNIQUE in CREATE TABLE, then every time cur.getCount() value is 1. I am new in SQLite. Please tell me whats the problem.
Your code looks like Ok. Maybe you shouldn't make KEY_MSG_DATE like UNIQUE. Try to get more info about what you want to do.
What you have implemented is that in every entry in every column has to be unique within the column but I assume what you want is that the row containing the columns msgBody, msgAddress and msgDate has to be unique within the table.
You can achieve that by placing all columns together in the UNIQUE clause:
UNIQUE(msgBody, msgAddress, msgDate) ON CONFLICT REPLACE