SQLite, Tables, Joining - android

Android, implementing SQLite
These are the tables i have:
http://postimg.org/image/jafsx39h7/
I have the code:
public String getWorkoutNameInfo() {
// TODO Auto-generated method stub
String[] columns = new String[] { KEY_DATE_OF_WORKOUT,
KEY_WORKOUT_NAME, KEY_DATE };
Cursor c = ourDatabase.query(TABLE_DATE_WORKOUT, columns, null, null,
null, null, null, null);
String workoutName2 = "";
int iWorkoutID = c.getColumnIndex(KEY_WORKOUT_NAME);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
workoutName2 = workoutName2 + c.getString(iWorkoutID);
}
return workoutName2;
}
This returns workoutName2 which is '2 1 2'
Now i need to look up the value for 2 in my WorkoutTable and return 'Back' and produce 'Back,Chest,Back' so i can out put that onto my screen instead of 2 1 2.
I understand I'll be using a JOIN statement? However i'm having no luck implementing it.
My Table Coding:
// WORKOUT TABLE - COLUMN NAMES
public static final String KEY_WORKOUT = "workout_id";
public static final String STRING_WORKOUT = "workout_name";
// DATE OF WORKOUT TABLE - COLUMN NAMES
public static final String KEY_DATE_OF_WORKOUT = "date_of_workout_id";
public static final String KEY_DATE = "date_of_workout";
public static final String KEY_WORKOUT_NAME = "workout_id";
//TABLE NAMES
private static final String TABLE_WORKOUT = "WorkoutTable";
private static final String TABLE_DATE_WORKOUT = "DateofWorkout";
Here is my attempt:
public String test(String workoutSelectedNameInfo) {
// TODO Auto-generated method stub
String NAMEofWorkout = "";
open();
ourDatabase = ourhelper.getReadableDatabase();
Cursor c = ourDatabase
.rawQuery(
"SELECT * FROM WorkoutTable LEFT JOIN DateofWorkout ON (WorkoutTable.workout_id = DateofWorkout.workout_id) WHERE workout_id = ?",
new String[] { "2" });
int iDateofWorkoutsWorkoutId = c.getColumnIndex(KEY_WORKOUT_NAME);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
NAMEofWorkout = NAMEofWorkout + c.getString(iDateofWorkoutsWorkoutId);
}
c.close();
ourDatabase.close();
System.out.println(NAMEofWorkout);
return NAMEofWorkout;
}
HOWEVER When it output the 'NameofWorkout' which SHOULD be Chest,Back,Chest i receive nothing at all, absolutely blank.

When I enter your data into a SQLite instance on my machine and then execute your query, I get the following error:
Error: ambiguous column name: workout_id
In the query, changing WHERE workout_id to WHERE DateofWorkout.workout_id makes the error go away.
This problem happens because there are two columns named workout_id in the result, and you must disambiguate your subsequent references. Because of this, you probably must also change
c.getColumnIndex(KEY_WORKOUT_NAME)
to
c.getColumnIndex(TABLE_DATE_WORKOUT + "." + KEY_WORKOUT_NAME)
when you make use of the results later.

Related

Android SQLite: Is this possible to avoid insert same variable

I am wondering if its possible to query existing database and detect if same value is in the database when inserting.
This is method of inserting in a class extends SQLiteOpenHelper
public void insertTimeTable_Schedule(String title, String subtitle, String color_text, String color_text_bg,
String mon, String tue, String wed, String thus, String fri, String sat, String sun,
String start_time, String end_time){
sqLiteDatabase = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_TITLE,title);
values.put(COLUMN_SUBTITLE,subtitle);
values.put(COLUMN_COLOR_TEXT,color_text);
values.put(COLUMN_COLOR_TEXT_BG,color_text_bg);
values.put(COLUMN_MON,mon);
values.put(COLUMN_TUE,tue);
values.put(COLUMN_WED,wed);
values.put(COLUMN_THUS,thus);
values.put(COLUMN_FRI,fri);
values.put(COLUMN_SAT,sat);
values.put(COLUMN_SUN,sun);
values.put(COLUMN_START_TIME,start_time);
values.put(COLUMN_END_TIME,end_time);
sqLiteDatabase.insert(TABLE_TIMETABLE, null, values);
}
Now I'd like to detect and make error message if there is same start_time in COLUMN_START_TIME when inserting new table data.
I tried to display values from database using method will be indicated below, and this will show everything I inserted
public String getData_database(){
sqLiteDatabase = this.getReadableDatabase();
String[] columns = new String[]{KEY_ID, COLUMN_TITLE,COLUMN_SUBTITLE,COLUMN_COLOR_TEXT,COLUMN_COLOR_TEXT_BG,
COLUMN_MON,COLUMN_TUE, COLUMN_WED,COLUMN_THUS, COLUMN_FRI,COLUMN_SAT,COLUMN_SUN,
COLUMN_START_TIME,COLUMN_END_TIME};
#SuppressLint("Recycle")
Cursor cursor =
sqLiteDatabase.query(TABLE_TIMETABLE,columns,null,null,null,null,null);
int iId = cursor.getColumnIndex(KEY_ID);
int iTitle = cursor.getColumnIndex(COLUMN_TITLE);
int iTextcolor = cursor.getColumnIndex(COLUMN_COLOR_TEXT);
int iTextBgcolor = cursor.getColumnIndex(COLUMN_COLOR_TEXT_BG);
int iSubtitle = cursor.getColumnIndex(COLUMN_SUBTITLE);
int iStarttime = cursor.getColumnIndex(COLUMN_START_TIME);
int iEndtime = cursor.getColumnIndex(COLUMN_END_TIME);
StringBuilder result = new StringBuilder();
for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()){
result.append("Id: ").append(cursor.getString(iId)).append("\n").append("Title: ").append(cursor.getString(iTitle)).append("\n").append("SubTitle: ").append(cursor.getString(iSubtitle)).append("\n").append("Text Color: ").append(cursor.getString(iTextcolor)).append("\n").append("Text BG Color: ").append(cursor.getString(iTextBgcolor)).append("\n").append("Start Time: ").append(cursor.getString(iStarttime)).append("\n").append("End Time: ").append(cursor.getString(iEndtime)).append("\n\n");
}
sqLiteDatabase.close();
return result.toString();
}
If you have any advice, I'd love to hear.
You can have a method that returns a boolean after querying the table. Then in your insert statement you check if the response is true, then show whatever error, otherwise, insert the record.
This method:
public boolean existsStartTime(String start_time){
sqLiteDatabase = this.getWritableDatabase();
String sql = "SELECT 1 FROM " + TABLE_TIMETABLE + " WHERE " + COLUMN_START_TIME + " = ?";
Cursor c = sqLiteDatabase.rawQuery(sql, new String[] {start_time});
boolean result = c.moveToFirst();
c.close();
sqLiteDatabase.close();
return result;
}
will return true if the value of the variable start_time exists in the table or false if it does not exist.
You can check it like:
String start_time = "<value here>";
if (existsStartTime(start_time)) {
<error message here>
} else {
insertTimeTable_Schedule(...);
}

Android, sqlite database finding two values in the two columns and the resulting value

im constructing an android application which use a large pre populated datbase of 910,000 records which includes 4 columns. These columns are windspeed, latitude, longitude and _id. What im trying to do is construct an sqlite query that finds a lav value in the latitude column and long (longitude) value in the longitude and the windspeed at which these two columns meet.
So the table would look something like this:
_id..............Latitude..................Longitude..............WindSpeed
1..................-9.4869363.............61.3704805..............7
2.................-7.6257292...............60.9958851..............8
3.................-9.4869363................60.9958851..............10
so if i was use the above table the lat value i would want to find would -9.4869363 and the long value would be 60.9958851 and thus the windspeed would be the line that both of these meet e.g from the table line 3 and thus the wind speed is 10
To do this ive tried using this line of code but i dont think it is correct
public class MyDatabase extends SQLiteAssetHelper {
private static final String DATABASE_NAME = "WindSpeed.sqlite";
private static final int DATABASE_VERSION = 1;
private static final String LAT_VAL = "Latitude";
private static final String LONG_VAL = "Longitude";
private static final String WIND_SPEED= "Speed10m";
private static final String ROW_ID= " _id";
double lat= 3.52;
double Long = 65.42;
public MyDatabase(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public Cursor getWindSpeed2(){
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String [] sqlSelect = {WIND_SPEED,};
String sqlTables = "noabl_10m_out";
String whereClause = "LAT_VAL = ? AND LONG_VAL = ?";
String[] whereArgs = new String[] {
"lat",
"Long"
};
qb.setTables(sqlTables);
Cursor d = qb.query(db, sqlSelect, whereClause, whereArgs,
null, null, null);
d.moveToFirst();
return d;
}
}
Is this wrong, ive searched far and wind and i just keep getting confused tbh so any help would be massive thanks
It seems that you are not using the column names but instead the variable names.
Try to change the whereClause to:
String whereClause = LAT_VAL + "=? AND " + LONG_VAL + "=?";
Also the whereArgs to:
String[] whereArgs = new String[] {
String.valueOf(lat),
String.valueOf(Long)
};
There are many mistakes in your code and I'm starting to think that you have no idea what you're doing.. Unnecessary comma here:
String [] sqlSelect = {WIND_SPEED,};
Change
String whereClause = "LAT_VAL = ? AND LONG_VAL = ?";
to
String whereClause = LAT_VAL+" = ? AND "+LONG_VAL+" = ?";
and
String[] whereArgs = new String[]
{
"-9.4869363",
"60.9958851"
};
to
String[] whereArgs = new String[]
{
"lat",
"Long"
};
LAT_VAL and LONG_VAL are variable that you use to store the columns name so they should be outside the quotes and whereArgs needs to contain the values that you want to compare

SQLite - creating multiple tables that update or insert

i am having problem inserting and updating values correctly into the database. I have a database, with two tables each with 3 columns DATE, NUM_X, NUM_Y. The two different tables contain the same columns, the only difference in the way values are inserted is that the HOURS_TABLE will take HH (the current hour of the day) and DATE_TABLE will take a short time string dd/MM/yyyy.
The values are not being inserted into new rows, but updating the values of the first row. Both tables currently have only one row.
public static final String HOURS_TABLE = "HOURS_TABLE";
public static final String DATE_TABLE = "DATE_TABLE";
public static final String CreateHoursTable = "create table "+
HOURS_TABLE +" ("+DATE+" string not null, "+NUM_X+
" integer default 0,"+NUM_Y+" integer default 0)";
public static final String CreateDateTable = "create table "+
DATE_TABLE +" ("+DATE+" string not null, "+NUM_X+"
integer default 0,"+NUM_Y+" integer default 0)";
#Override
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
db.execSQL(CreateDateTable);
db.execSQL(CreateHoursTable);
}
Two different kinds of date strings could be passed in, on formatted dd/MM/yyyy (short date string )and another for HH (hours)
public long createEntry(int x, int y, String date, int Version_Zero_HoursTable_One_DateTable)
{
/*
* first grab the values needed to increment the database values
* */
Cursor c ;
String[] column = new String[]{DATE,NUM_X,NUM_Y};
if(Version_Zero_HoursTable_One_DateTable == 0)
{
c = ourDatabase.query(HOURS_TABLE, column, date, null, null,
null, null);
}
else
{
c = ourDatabase.query(DATE_TABLE, column, date, null, null,
null, null);
}
int current_x =0;
int current_y = 0;
String current_day = "";
int iX = c.getColumnIndex(NUM_X);
int iY = c.getColumnIndex(NUM_Y);
int iDate = c.getColumnIndex(DATE);
for(c.moveToFirst(); !c.isAfterLast(); c.moveToNext()){
current_x += c.getInt(iX);
current_y += c.getInt(iY);
current_day = c.getString(iDate);
}
ContentValues cv = new ContentValues();
cv.put(NUM_X, smokes+current_smokes);
cv.put(NUM_Y, cravings+current_cravings);
cv.put(DATE, date);
the WHEREargs string is my variable for a where clause, so when the selected DATE from the database equals date it will update that selected column, and if nothing is selected (current_day.equals("")), the statement to insert a new row will execute.
String WHEREargs = DATE+"="+date;
if(Version_Zero_HoursTable_One_DateTable == 0)
{
if(current_day.equals(""))
{
return ourDatabase.insert(HOURS_TABLE, null, cv);
}
else
{
return ourDatabase.update(HOURS_TABLE, cv, WHEREargs, null);
}
}
else
{
if(current_day.equals(""))
{
return ourDatabase.insert(DATE_TABLE, null, cv);
}
else
{
return ourDatabase.update(DATE_TABLE, cv, WHEREargs, null);
}
}
}
any help would be greatly appreciated , Thankyou .
You are using the date variable wrong.
A date value such as 24/03/2014 cannot be directly used as a WHERE expression; it would be interpreted as two integer divisions.
Similarly, a string such as DATE = 24/03/2014 cannot be used as a WHERE expression either, because it compares the value in the date column to a number.
In SQL, strings must be enclosed in 'single quotes'.
However, to avoid formatting problems and SQL injection attacks, it is a better idea to use parameters:
String where = DATE + "= ?";
String[] whereArgs = new String[] { date };
...
db.query(..., where, whereArgs, ...);

Get data from database Android

I have a page which can retrieve user data from database
but after whole day of trying, I am only able to get the table column name but not the value inside.
this is my code to create database
public static final String LASTLOGIN = "lastuser";
public static final String USER_ID = "suser_id";
public static final String USER_NAME = "suser_name";
public static final String USER_PASSWORD = "spassword";
public static final String PRIME_ID = "id";
private static final String TABLE_USER =
"create table "+ LASTLOGIN+" ("
+PRIME_ID+" integer primary key autoincrement, "
+ USER_ID + " text, "
+ USER_NAME +" text, "
+USER_PASSWORD+" text); ";
and here is the function implemented to get user data
public Cursor getuser()
{
String[] columns = new String[]{PRIME_ID, USER_NAME, USER_PASSWORD};
Cursor cursor = sqLiteDatabase.query(
LASTLOGIN, columns, null, null, null, null, PRIME_ID +" DESC");
Log.d("TAG", columns[1]);
return cursor;
}
and here is my code to display the result
mySQLiteAdapter = new SQLiteAdapter(this);
mySQLiteAdapter.openToWrite();
cursor = mySQLiteAdapter.getuser();
String[] resultvalue = new String{
SQLiteAdapter.PRIME_ID,SQLiteAdapter.USER_NAME, SQLiteAdapter.USER_PASSWORD};
Toast.makeText(this, resultvalue[0]+resultvalue[1], Toast.LENGTH_LONG).show();
and the toast result only show the column name but not the value inside, is there any mistake i made? and I want to set limit to 1, but where to set it?
Thanks for helping me
the way you try reading the values is completly wrong.
you create an array
String[] resultvalue = new String[]{
SQLiteAdapter.PRIME_ID,
SQLiteAdapter.USER_NAME,
SQLiteAdapter.USER_PASSWORD};
after that you read the values 0 and 1 from this array.
Your toast works absolutly correctly becouse inside this array you define the column names!
If you want to show the values from your query do it this way:
while(cursor.moveToNext()){
Integer str1 = str 1 + cursor.getInteger(1);
String str2 =str2 + cursor.getString(2);
Toast.makeText(this, str1 + str2, Toast.LENGTH_LONG).show();
}
or a better way receiving the correct index:
cursor.getInteger( cursor.getColumnIndex(SQLiteAdapter.PRIME_ID) );
cursor.getString( cursor.getColumnIndex(SQLiteAdapter.USER_NAME) );
Please note when retrieving data from a database, you store it in a Cursor in the memory and hence can only access it using that particular Cursor object, which you have used in the following line of code.
Cursor cursor = mySQLiteAdapter.getuser();
The Following line retrieves the column names and not the values.
String[] resultvalue = new String[]{SQLiteAdapter.PRIME_ID,SQLiteAdapter.USER_NAME, SQLiteAdapter.USER_PASSWORD};
So the following is doing what you have asked it to do, retrieve column names not values
Toast.makeText(this, resultvalue[0]+resultvalue[1], Toast.LENGTH_LONG).show();
You need something like following:
if(cursor.getCount() != 0)
{
while(cursor.moveToNext())
{
resultvalue [0] = csr.getString(0);
resultvalue [1] = csr.getString(1);
//....
}
}
Hope this helps
here is my solution:
final String TABLE_NAME = "table_name";
String selectQuery = "SELECT Column FROM "+TABLE_NAME+" WHERE column='"+some_value+"'";
SQLiteDatabase db = this.openDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
String[] data = new String[cursor.getCount()];;
int i = 0;
if (cursor.moveToFirst()) {
do {
i=Integer.parseInt(cursor.getString(cursor.getColumnIndex("value")));
} while (cursor.moveToNext());
}
cursor.close();

Failing to query the max number in database

I am trying to find the max number in a column of one of the tables in my database.
I thought I had this one sorted (I posted similar question previously), however after some testing I have realised my code isn't working as I thought.
The database consists of a table with the following columns:
_id, inspection_link, area_number, area_reference
I have created the following code in my database helper class:
public static final String AREAS_TABLE = "areas";
public static final String AREA_ID = "_id";
public static final String AREA_NUMBER = "area_number";
public static final String AREA_REF = "area_reference";
public static final String AREA_LINK = "area_link";
public static final String INSPECTION_LINK = "inspection_link";
public Cursor selectMaxAreaNumber (long inspectionId) {
String inspectionIdString = String.valueOf(inspectionId);
String[] tableColumns = new String[] {
AREA_NUMBER,
"(SELECT max(" + AREA_NUMBER + ") FROM " + AREAS_TABLE + ") AS max"
};
String whereClause = INSPECTION_LINK + " = ?";
String[] whereArgs = new String[] {
inspectionIdString
};
Cursor c = rmDb.query(AREAS_TABLE, tableColumns, whereClause, whereArgs,
null, null, null);
if (c != null) {
c.moveToFirst();
}
c.close();
return c;
}
Then in the activity where I want to query the database I have written the following:
public class AreaEdit extends Activity {
private EditText AreaNumber;
private EditText AreaReference;
private Button saveButton;
private Button cancelButton;
protected boolean changesMade;
private AlertDialog unsavedChangesDialog;
private RMDbAdapter rmDbHelper;
private long inspectionId;
private long areaId;
private int nextAreaNumber = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rmDbHelper = new RMDbAdapter(this);
rmDbHelper.open();
Intent i = getIntent();
inspectionId = i.getLongExtra("Intent_InspectionID", -1);
areaId = i.getLongExtra("Intent_AreaID", -1);
if (areaId == -1) {
Cursor c = rmDbHelper.selectMaxAreaNumber(inspectionId);
startManagingCursor(c);
c.moveToFirst();
nextAreaNumber = c.getInt(c.getColumnIndex("max")) + 1;
}
setContentView(R.layout.edit_area);
setUpViews();
populateFields();
setTextChangedListeners();
}
private void setUpViews() {
AreaNumber =(EditText)findViewById(R.id.area_number);
AreaReference =(EditText)findViewById(R.id.area_reference);
saveButton = (Button)findViewById(R.id.area_save_button);
cancelButton = (Button)findViewById(R.id.area_cancel_button);
}
private void populateFields() {
if (areaId > 0) {
Cursor c = rmDbHelper.fetchArea(areaId);
startManagingCursor(c);
c.moveToFirst();
AreaNumber.setText(c.getString(
c.getColumnIndexOrThrow(RMDbAdapter.AREA_NUMBER)));
AreaReference.setText(c.getString(
c.getColumnIndexOrThrow(RMDbAdapter.AREA_REF)));
c.close();
}
else {
AreaNumber.setText(String.valueOf(nextAreaNumber));
}
}
However, when it returns the wrong number - it seems to pick up the maximum number from the whole table which includes data from other inspections.
I guess this may be down to the conversion between Strings and Longs etc maybe, but I have a brickwall with this?
Any help much appreciated.
You can simply try below:
String sql = "SELECT MAX(ColumnNameHere) AS MaxValue FROM myTable WHERE AnotherColumn = 'SomValue'";
Cursor c = db.rawQuery(sql, null);
c.moveToFirst();
c.getInt(c.getColumnIndex("MaxValue"));
Detailed solution to this question found here:
Solution to this detailed in the following post: SELECT statement not returning MAX number
Basically, it was an issue with the query as thought and how I used the cursor.

Categories

Resources