I have table ( id , text) and I need to swap two values in columns like this:
Before.
1 one.
2 two.
3 three.
After ( 1 and 3 swap)
1 three
2 two
3 one
To update each row, you need something like this:
void updateMyTableText (MyTableRow row)
{
ContentValues values = new ContentValues();
values.put ("text", MyTableRow.text);
String where = "id = ?";
String[] whereArgs = new String[1];
whereArgs[0] = Long.toString (row.id);
getDb().update ("MyTable", values, where, whereArgs);
}
where MyTableRow is
class MyTableRow
{
long id;
String text;
}
You'll also need some queries to get the "text" for rows 1 and 3.
Here's one way to do a query:
long getId (String text)
{
// do the query
String query = "select id from MyTable where text = ? ";
String[] args = new String[1];
args[0] = text;
Cursor cursor = getDb().rawQuery (query, args);
if (cursor == null)
throw new IllegalStateException ("cursor is null");
try
{
// get the results
if (!cursor.moveToNext())
return -1; // row not found
long id = cursor.getLong (0);
return id;
}
finally
{
cursor.close();
}
}
Are you trying to change the values in the rows themselves? Most databases systems don't let you arbitrarily swap values since there is an assumption that they are permanently associated. You could issue UPDATE commands to permanently modify the values, but doing this temporarily will probably be an issue handled once the data is returned.
UPDATE table_name
SET text=three
WHERE id=1;
UPDATE table_name
SET text=one
WHERE id=3;
// Assuming id1 < id2
void swap(id1,id2)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues CV = new ContentValues();
// First get the 2 rows
Cursor res = db.rawQuery("SELECT COLUMN_NAME FROM "+ TABLE_NAME +" WHERE ID IN ("+id1+","+id2+") ORDER BY ID ASC",null);
res.moveToFirst();
CV.put("COLUMN_NAME",res.getString(0));
//Update 1st row with 2nd item
db.update(TABLE_NAME,CV,"ID = ?",new String[]{id2+""});
res.moveToNext();
CV.put("COLUMN_NAME",res.getString(0));
//Update 2nd row with 1st item
db.update(TABLE_NAME,CV,"ID = ?",new String[]{id1+""});
}
Hope it helps!!
Related
I am new to Android and need to display Starttime, Stoptime and Name in a Listview. For displaying I use a SimpleAdapter. The problem is that I have two SQLite tables:
Table time:
Starttime | Stoptime | Student ID
Table student:
Student ID | Student name
Right now, I use a Cursor to get Starttime, Stoptime and Student ID from my database
Cursor curm1 = myDb.getAllMonday();
while (curm1.moveToNext()) {
final HashMap<String, String> resultMapMonday = new HashMap<>();
resultMapMonday.put("Start", curm1.getString(3));
resultMapMonday.put("Stop", curm1.getString(4));
resultMapMonday.put("Student", curm1.getString(5));
arrayListStudentsName.add(curm1.getString(5));
listItemsMo.add(resultMapMonday);
}
and then a SimpleAdapter to display it:
final SimpleAdapter adaptersimpleMo = new SimpleAdapter(this, listItemsMo, R.layout.timeslots_configurate,
new String[]{"Start", "Stop", "Student"},
new int[]{R.id.oneTime_start, R.id.oneTime_stop, R.id.selectedStudent});
But instead of the id, I want to display the names, which are stored in the other table. I can get the matching names of the Ids with another cursor
Cursor curm2 = myDb.getNamesbyIDs(arrayListStudentsName);
while (curm2.moveToNext()) {
final HashMap<String, String> resultMapNames = new HashMap<>();
resultMapNames.put("Name", curm2.getString(1));
}
But I don't know how to get the names in the same adapter to display the names in the same list Item as the matching start & stop time.
EDIT
public Cursor getAllMonday() {
SQLiteDatabase db = this.getWritableDatabase();
Cursor res = db.rawQuery("SELECT * FROM " + TABLE_TIME + " WHERE day = 'Montag' ORDER BY CAST(start as unsigned)", null);
return res;
}
Change getAllMonday() to use a query that joins the 2 tables:
public Cursor getAllMonday() {
SQLiteDatabase db = this.getWritableDatabase();
String sql = "SELECT t.Start, t.Stop, s.Studentname FROM " + TABLE_TIME + " AS t INNER JOIN " + TABLE_STUDENT +
" AS s ON s.StudentID = t.StudentID WHERE t.day = 'Montag' ORDER BY CAST(t.start as unsigned)"
Cursor res = db.rawQuery(sql, null);
return res;
}
Change the table variable TABLE_STUDENT and the column names that I used to the actual ones.
Now the cursor contains the name of the student and not the id.
Next change the code to:
Cursor curm1 = myDb.getAllMonday();
while (curm1.moveToNext()) {
final HashMap<String, String> resultMapMonday = new HashMap<>();
resultMapMonday.put("Start", curm1.getString(curm1.getColumnIndex("Start")));
resultMapMonday.put("Stop", curm1.getString(curm1.getColumnIndex("Stop")));
resultMapMonday.put("Student", curm1.getString(curm1.getColumnIndex("Studentname")));
arrayListStudentsName.add(curm1.getString(curm1.getColumnIndex("Studentname")));
listItemsMo.add(resultMapMonday);
}
curm1.close();
I have a table in which name and number of people are stored. Now I want to make a method in sqlite helper class which will return the number of particular person whose name I will pass in the method
There is something wrong with my code.
Here is my code
public String fetchGroup(SQLiteDatabase inDatabase, String valueCheck){
String query = "SELECT * FROM groups WHERE groupname='" + valueCheck;
Cursor cursor = inDatabase.rawQuery(query,null);
String place = cursor.getString(cursor.getColumnIndex("contactid"));
return place;
Take care to use cursor.moveToFirst() command before reading datas
Else, instead counting the number of people in Java, you can just modify your query to have only this number return.
Something like this :
public String fetchGroup(SQLiteDatabase inDatabase, String valueCheck){
String query = "SELECT COUNT(id) FROM groups WHERE groupname=\"" + valueCheck + "\"";
Cursor cursor = inDatabase.rawQuery(query, null);
cursor.moveToFirst();
int place = cursor.getInt(0);
return String.valueOf(place);
}
After your query do
int count = 0;
while (cursor.moveToNext()) {
// increment variable
count++;
}
after iterating you will get number of count
im trying to update specific row but no luck.
Im first time working with sqlite, maybe its true im confused with column/row
In ideal i want update text in field with name MESSAGE_HISTORY(id=5)
Same way and code works for field Item0 (id = 1)
public static void updateHistory(ArrayList<MessageModel> models, String id) {
if (database != null) {
Cursor c = database.query(TDatabaseHelper.DATABASE_TABLE,null,null, null, null, null, null);
if (c.moveToFirst()) {
do {
int index1 = c.getColumnIndex(MESSAGE_HISTORY);//return position 5
ContentValues data = new ContentValues();
data.put(MESSAGE_HISTORY, DatabaseHelper.chatHistoryModelsConvert(models, id).toString());
long k = database.update(TDatabaseHelper.DATABASE_TABLE, data, "id=" + index1, null);
DBLogger.w("DATABASE UPDATE STATUS = "+k);
}while(!c.moveToFirst());
}else {
DBLogger.d("Error");
}
}
}
K always return 0
Any help ?
[UPD]
public static void CreateDB() {
if (database != null) {
Cursor c = database.query(TDatabaseHelper.DATABASE_TABLE, null, null, null, null, null, null);
if (!c.moveToFirst()) {
cv.put(TDatabaseHelper.ITEM0, "Item0"); // <---- this item update very good index = 1
cv.put(TDatabaseHelper.MESSAGE_HISTORY, "history"); <-- cant update, index = 5;
cv.put(TDatabaseHelper.ITEM1, "item1");
cv.put(TDatabaseHelper.ITEM2, "item2");
cv.put(TDatabaseHelper.ITEM3, "item3");
long rowID = database.insert(TDatabaseHelper.DATABASE_TABLE, null, cv);
DBLogger.i("row inserted, ID = " + rowID);
}
}
}
[UPD]
this not help :(
String[] args = new String[]{""+index1}; ??database.update(TDatabaseHelper.DATABASE_TABLE, data, "id=?", args);
The following line gives you the index of the column named MESSAGE_HISTORY but it does not give you the value.
int index1 = c.getColumnIndex(MESSAGE_HISTORY);//return position 5
As a result of this, your line
long k = database.update(TDatabaseHelper.DATABASE_TABLE, data, "id=" + index1, null);
updates a row that has an id of "5" and it seems that it does not exist. You need to get the value in column 5, so do something like the following:
String messageValue = c.getString(index1);
long k = database.update(TDatabaseHelper.DATABASE_TABLE, data,
MESSAGE_HISTORY + " = ?", new String[] {messageValue});
It is better to use the whereArgs here since just appending messageValue may cause problems. See the update documentation regarding the whereClause and whereArgs.
In any case, slap the debugger on that last line to see exactly what you are passing to the update method. You may be surprised.
I have several tables. I have a query also. My problem is to generate the SQL query dynamically using Java.
I have the following fields in a separate table:
Collumn name status
po_number, Y
unit_cost, Y
placed_date , Y
date_closed, Y
scheduled_arrival_date Y
date_closed Y
order_quantity Y
roll_number N
product_sku N
product_category_name N
rec_vendor_quantity Y
vendor_name Y
et_conversion_unit_quantity Y
from which i have to generate a query when the status is Y, the problem here is some time the above columns
The following query is the out put of the above :
here i have inculded all the columns but i have to exculde the column which has the status of N, please help me to construt the query using java.
select
pi.po_number,poi.unit_cost,pi.placed_date CreateDate,
case when isnull(pi.date_closed) then pi.scheduled_arrival_date
else pi.date_closed end as ReceviedDate,
poi.order_quantity,poi.roll_number,p.product_sku product_name,
pc.product_category_name,poi.rec_vendor_quantity,pv.vendor_name,p.et_conversion_unit_quantity,pi.note
from
purchase_order as pi,
purchase_order_inventory as poi,
product_vendors as pv,
products AS p,
product_categories AS pc
where
pi.purchase_order_id=poi.purchase_order_id and
pc.product_category_id=p.product_category_id and
poi.product_id = p.product_id and
poi.product_category_id=pc.product_category_id and
pi.vendor_id=pv.product_vendor_id and
( ( pi.date_closed >= '2012-01-01' and pi.date_closed <='2012-09-05 23:59:59' )
or ( pi.scheduled_arrival_date >= '2012-01-01' and pi.scheduled_arrival_date <='2012-09-05 23:59:59') ) and
pi.po_type=0
and pi.status_id = 0 and poi.transaction_type = 0
order by pi.po_number
UPDATE :
QUERY : STEP 1:
SELECT rcm.id,rcm.tablename,rcm.columnname,rcm.size,rcm.displayorder,rcm.isactive FROM report_customise_master rcm where rcm.tablename !='employee' and rcm.isactive='Y' order by rcm.displayorder;
STEP 2 :
Java method to construct the query :
public Map getComplexReportQuery() {
String query = "SELECT rcm.id,rcm.tablename,rcm.columnname,rcm.size,rcm.displayorder,rcm.isactive FROM report_customise_master rcm where rcm.tablename !='employee' and rcm.isactive='Y' order by rcm.displayorder;";
String tableName = "", from = "", select = "";
StringBuffer sb = new StringBuffer();
Map<String, List<String>> resultsMap = new LinkedHashMap<String, List<String>>();
Map<String, String> displayOrderMap = new LinkedHashMap<String, String>();
Map queryMap = new LinkedHashMap();
if (!query.isEmpty() || query.length() > 0) {
sb.append(query);
}
Connection connection = getConnection();
if (connection != null) {
try {
PreparedStatement reportQueryPS = connection.prepareStatement(sb.toString());
ResultSet reportQuery_rst = reportQueryPS.executeQuery();
List<String> tables = new ArrayList<String>();;
if (reportQuery_rst != null) {
StringBuilder selectQuery = new StringBuilder(" SELECT ");
StringBuilder fromQuery = new StringBuilder(" FROM ");
while (reportQuery_rst.next()) {
tableName = reportQuery_rst.getString("tablename");
List<String> columns = resultsMap.get(tableName);
if (columns == null) {
columns = new ArrayList<String>();
resultsMap.put(tableName, columns);
}
columns = resultsMap.get(tableName);
String columnName = reportQuery_rst.getString("columnname");
columns.add(columnName);
}
tableName = "";
for (Entry<String, List<String>> resultEntry : resultsMap.entrySet()) {
tableName = resultEntry.getKey();
List<String> columns = resultEntry.getValue();
int i = 0;
for (String column : columns) {
selectQuery.append(tableName + "." + column);
if (i != columns.size()) {
selectQuery.append(",");
} else {
selectQuery.append("");
}
i++;
}
if (!tables.contains(tableName)) {
tables.add(tableName);
}
}
//to remove comma at the end of line
select = selectQuery.toString().replaceAll(",$", "");
tableName = "";
int i = 0;
for (String table : tables) {
fromQuery.append(table);
fromQuery.append(" ");
fromQuery.append(table);
if (i != tables.size()) {
fromQuery.append(",");
} else {
fromQuery.append("");
}
i++;
}
from = fromQuery.toString().replaceAll(",$", "");
queryMap.put("query", select + from);
}
//from = from+"ORDER BY "+orderbyColumn+" "+sort+" ";
} catch (Exception ex) {
ex.printStackTrace();
} finally {
try {
closeConnection(connection, null, null);
} catch (Exception ex) {
ex.printStackTrace();
}
}
} else {
System.out.println("Connection not Established. Please Contact Vendor");
}
return queryMap;// return the map/ list which contains query and sory and display order
}
STEP 3 : Result query
{query= SELECT purchase_order.po_number,purchase_order.placed_date,purchase_order.date_closed,purchase_order.scheduled_arrival_date,purchase_order_inventory.unit_cost,purchase_order_inventory.order_quantity,purchase_order_inventory.roll_number,purchase_order_inventory.rec_vendor_quantity,products.product_sku,products.et_conversion_unit_quantity,product_categories.product_category_name ,product_vendors.vendor_name FROM purchase_order purchase_order,purchase_order_inventory purchase_order_inventory,products products,product_categories product_categories,product_vendors product_vendors}
but this not what i wanted, Please help me to construct the query i have given.
Two queries
You need to make two queries:
Query which fields are enabled
Build the second query string (the one you want to build dinamically)
It's this way because a SQL query has to tell which columns will be included before querying any data. In fact it will be used to build the internal DB query plan, it is, the way the DB motor will use to retrieve and organize the data you ask.
Query all columns
Is it necesary to query only that fields? Can't you query everything and use the relevant data?
Joins
Looking at the updated question I guess you need to dynamically add where conditions to join tables correctly. What I should do is have a reference telling me what coindition to add when a table is present.
There are at least two options:
Based on table pairs present (by example: "if A and B are present then add A.col1 = B.col2")
Based on tables present ("if B is present, then add A.col1 = B.col2; A should be present"
Based on your example I think the second option is more suitable (and easy to implement).
So I should have some static Map<String, JoinInfo> where JoinInfo has at least:
JoinInfo
+ conditionToAdd // by example "A.col1 = B.col2"
+ dependsOnTable // by example "A" to indicate that A must be present when B is present
So you can use:
that info to add tables that should be (by example: even if A has no selected cols, must be present to join with B)
include the conditionToAdd to the where clause
Anyway... I think you are getting into much trouble. Why so dynamic?
You have to approach the thing step by step.
Firstly you have to create a query that will return all rows that have status='Y'
Then you will put the COLUMN_NAME in a list of Strings.
List<String> list = new List<String>();
while(rs.next()){
list.add(rs.getString(columnNumber));
}
And then you have to loop the List and generate dynamically your second sql statement
String sqlSelect = "SELECT ";
String sqlFrom = " FROM SOME_OTHER_TABLE "
String sqlWhere = " WHERE SOME_CONDITION = 'SOME_VALUE' "
for(String x : list){
sqlFrom += x +" , "+;
}
//here make sure that you remove the last comma from sqlFrom because you will get an SQLException
String finalSql = sqlSelect + sqlFrom + sqlWhere ;
I have taken String value from a EditText and set it inside SELECT QUERY after WHERE condition
As
TextView tv = (TextView) findViewById(R.id.textView3);
EditTextet2 et = (EditText) findViewById(R.id.editText1);
String name = et.getText().toString();
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = '"+name+"'", null);
c.moveToNext();
tv.setText(c.getString(c.getColumnIndex("email")));
But it doesn't work. Any suggestions?
Try trimming the string to make sure there is no extra white space:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE TRIM(name) = '"+name.trim()+"'", null);
Also use c.moveToFirst() like #thinksteep mentioned.
This is a complete code for select statements.
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.rawQuery("SELECT column1,column2,column3 FROM table ", null);
if (c.moveToFirst()){
do {
// Passing values
String column1 = c.getString(0);
String column2 = c.getString(1);
String column3 = c.getString(2);
// Do something Here with values
} while(c.moveToNext());
}
c.close();
db.close();
Try using the following statement:
Cursor c = db.rawQuery("SELECT * FROM tbl1 WHERE name = ?", new String[] {name});
Android requires that WHERE clauses compare to a ?, and you then specify an equal number of ? in the second parameter of the query (where you currently have null).
And as Nambari mentioned, you should use c.moveToFirst() rather than c.moveToNext()
Also, could there be quotations in name? That could screw things up as well.
Here is the below code.
String areaTyp = "SELECT " +AREA_TYPE + " FROM "
+ AREA_TYPE_TABLE + " where `" + TYPE + "`="
+ id;
where id is the condition on which result will be displayed.
public User searchUser(String name) {
User u = new User();
SQLiteDatabase db = this.getWritableDatabase(); //get the database that was created in this instance
Cursor c = db.rawQuery("select * from " + TABLE_NAME_User+" where username =?", new String[]{name});
if (c.moveToLast()) {
u.setUsername(c.getString(1));
u.setEmail(c.getString(1));
u.setImgUrl(c.getString(2));
u.setScoreEng(c.getString(3));
u.setScoreFr(c.getString(4));
u.setScoreSpan(c.getString(5));
u.setScoreGer(c.getString(6));
u.setLevelFr(c.getString(7));
u.setLevelEng(c.getString(8));
u.setLevelSpan(c.getString(9));
u.setLevelGer(c.getString(10));
return u;
}else {
Log.e("error not found", "user can't be found or database empty");
return u;
}
}
this is my code to select one user and one only
so you initiate an empty object of your class then
you call your writable Database
use a cursor in case there many and you need one
here you have a choice Use : 1-
if (c.moveToLast()) { } //it return the last element in that cursor
or Use : 2-
if(c.moveToFirst()) { } //return the first object in the cursor
and don't forget in case the database is empty you'll have to deal with that in my case i just return an empty object
Good Luck
Detailed answer:
String[] selectionArgs = new String[]{name};
Cursor c = db.rawQuery(
"SELECT * FROM " + tabl1 +
" WHERE " + name + " = ? ", selectionArgs
);
selectionArgs : this takes the 'name' you desire to compare with, as argrument.
Here note "A Cursor object, which is positioned before the first entry of the table you refer to".
So,to move to first entry :
c.moveToFirst();
getColumnIndex(String ColumnName) : this returns the zero-based column index for the given column name.
tv.setText(c.getString(c.getColumnIndex("email")));
In case, you want to go searching through multiple rows for a given name under 'name' column then use loop as below:
if (cursor.moveToFirst()){
do{
////go traversing through loops
}while(cursor.moveToNext());
}
This should solve the problem.