In the DB I have implemented in my Android App, some columns are designed to contain text in different languages, for example this table:
CREATE TABLE "food" (
`_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
`ID` INTEGER NOT NULL UNIQUE,
`name` TEXT NOT NULL,
`name_it` TEXT,
`name_rus` TEXT,
`description` TEXT,
`description_it` TEXT,
`description_rus` TEXT,
`kcal` INTEGER,
`icon_food` TEXT,
`image_food` TEXT,
`category_id` INTEGER,
FOREIGN KEY(`category_id`) REFERENCES category ( _id )
)
I want to use a static String to keep the name of the column, translated according to the language of the User's device
public static final class FoodEntry implements BaseColumns {
public static final Uri CONTENT_URI =
BASE_CONTENT_URI.buildUpon().appendEncodedPath(PATH_FOOD).build();
public static final String TABLE_NAME = "food";
public static final String COLUMN_ID = "ID";
**public static final String COLUMN_NAME = Resources.getSystem().getString(R.string.food_COLUMN_NAME);**
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_ICON_FOOD = "icon_food";
public static final String COLUMN_CATEGORY_ID = "category_id";
public static Uri buildFoodUri(long id) {
return ContentUris.withAppendedId(CONTENT_URI, id);
}
}
Here the string.xml
<string name="food_COLUMN_NAME">name</string>
This does not work because of the following error:
Caused by: android.content.res.Resources$NotFoundException
How could I reach the goal to translate the column without touching more code? I wish to use a string resource that seems the perfect solution for my database structure
Related
This question already has answers here:
sqlite returned: error code = 1, msg = near ".....": syntax error [closed]
(3 answers)
Closed 7 years ago.
Hey guys I hope you can help me out here
I get this error but can't find how to solve the problem
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sergej.myapplication4/com.sergej.slidnerd_kopie.training.MeinePlaene_main}: android.database.sqlite.SQLiteException: near "SETSworkout": syntax error (code 1): , while compiling: CREATE SETSworkout(name TEXT)
That is the my Create Table
public class WorkoutDataHelper extends SQLiteOpenHelper {
public static final int DB_VERSION = 2;
public static final String DB_NAME = "dmworkouts.db";
public static final String WORKOUT_TABLE_NAME = "workouts";
public static final String SETS_TABLE_NAME = "workouts";
public static final String SESSIONS_TABLE_NAME = "sessions";
public static final String CREATE_WORKOUT_TABLE = "CREATE TABLE " + WORKOUT_TABLE_NAME +
" ( name TEXT )";
public static final String CREATE_SETS_TABLE ="CREATE SETS"+SETS_TABLE_NAME+"(name TEXT)";
public static final String CREATE_SESSIONS_TABLE = "CREATE TABLE " + SESSIONS_TABLE_NAME +
" ( time INTEGER, workoutid INTEGER, type INTEGER)";
public WorkoutDataHelper(Context context) {
super(context,DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_WORKOUT_TABLE);
db.execSQL(CREATE_SETS_TABLE);
db.execSQL(CREATE_SESSIONS_TABLE);
}
}
I think the problem is somewhere at CREATE_WORKOUT_TABLE but I tried to solve it but I did not make it.
You are missing a space when concatenating the strings :
"CREATE SETS"+SETS_TABLE_NAME+"(name TEXT)"
should be:
"CREATE SETS "+SETS_TABLE_NAME+"(name TEXT)"
hence the given error. You can see in the error messages that the word SET is not seperated from the table name making it a one word which makes the statement invalid.
I think I have checked all the previous posts on this issue but none seem to be helping me...
Basic stuff - trying to use a cursor adaptor bound to my database but I am getting:
java.lang.IllegalArgumentException: column '_id' does not exist
My schema has that column defined (although I do have 2 tables, both with the same name - is that an issue?), like this:
public static abstract class dbMain implements BaseColumns {
public static final String TABLE_NAME = "mpgMain";
public static final String ENTRY_ID = "_id";
public static final String VEHICLE_NAME = "v_name";
}
public static abstract class dbHistory implements BaseColumns {
public static final String TABLE_NAME = "mpgHistory";
public static final String ENTRY_ID = "_id";
public static final String TRIP_DATE = "date";
}
From other posts, I have put _id in my cursor porjection:
String[] projection = {dbMain.ENTRY_ID, dbMain.VEHICLE_NAME};
Cursor mpgCur = mpgDB.query(dbMain.TABLE_NAME, projection, null, null, null, null, null);
...but then my stack trace gives the same error, on the query line. If I remove the ENTRY_ID from the projection, the same error but on the later line instantiating the adaptor:
String[] fromColumns = {dbMain.VEHICLE_NAME};
int[] toViews = {R.id.displayVehicle};
SimpleCursorAdapter vehAdapter = new SimpleCursorAdapter(this,
R.layout.activity_first_screen, mpgCur, fromColumns, toViews, 0); <--- HERE
I've also tried putting a space in the CREATE TABLE command, before the _id field:
private static final String SQL_CREATE_MAIN_TABLE =
"CREATE TABLE " + dbMain.TABLE_NAME + " ( " +
dbMain.ENTRY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
Any ideas gratefully received...
If I'm not mistaken, by implementing BaseColumns, you don't have to specify "_id" in your schema. Just use the constant _ID (so, dbMain._ID and dbHistory._ID)
I need to know how to join 2 tables together. I am not sure how to do the joining of tables as I'm new to this.
I've created AnniversaryDBAdapter.class where I create 5 tables in one database. I just need to join 2 tables like join buddiesList table and likes table.
Below is the code of the AnniversaryDBAdapter.class
public class AnniversaryDBAdapter
{
private static final String DATABASE_NAME = "AllTables";
private static final int DATABASE_VERSION = 2;
private static final String CREATE_TABLE_BUDDIESLIST = " create table buddiesList(name_id integer primary key autoincrement, name text not null);";
private static final String CREATE_TABLE_LIKES = " create table likes(name_id integer primary key autoincrement,likes text not null);";
private static final String CREATE_TABLE_DISLIKES = " create table dislikes(name_id integer primary key autoincrement, dislikes text not null);";
private static final String CREATE_TABLE_EVENTS = "create table events(date_id integer primary key autoincrement, name_id text not null, date text not null, title_id text not null, starttime text not null, endtime text not null);";
private static final String CREATE_TABLE_TITLE = "create table titles(title_id integer primary key autoincrement, name text not null, image text not null);";
private final Context context;
private static final String TAG = "DBAdapter";
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public AnniversaryDBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_BUDDIESLIST);
db.execSQL(CREATE_TABLE_LIKES);
db.execSQL(CREATE_TABLE_EVENTS);
db.execSQL(CREATE_TABLE_TITLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version "+oldVersion+" to "+newVersion+", which will destroy all old data");
onCreate(db);
}
}
public AnniversaryDBAdapter open() throws SQLException
{
this.db = this.DBHelper.getWritableDatabase();
return this;
}
public void close()
{
this.DBHelper.close();
}
}
Assuming we correct your table layout to something like this:
CREATE TABLE buddiesList(
_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
name TEXT NOT NULL
);
CREATE TABLE likes (
_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
buddy_id INTEGER REFERENCES buddiesList(_id) ON DELETE CASCADE NOT NULL,
likes TEXT NOT NULL
);
Now, in your setup you can create a VIEW of the JOIN between buddiesList and likes, it will act like a normal table when selecting - you just can't update/delete or insert from it (without messing around with TRIGGERs of course).
CREATE VIEW buddyLikes AS
SELECT buddiesList.*, likes._id AS likes_id, likes.likes as likes
FROM buddiesList LEFT JOIN likes ON buddiesList._id=likes.buddy_id;
A View is created using execSQL - just like a table or trigger.
With a view you can select from a join between buddies and likes, returning all buddies and all their likes, like so:
SELECT * from buddyLikes;
which would return something like this:
_id name likes_id likes
1 |Ted |5 |Facebook
1 |Ted |4 |Murder
2 |Ed |1 |Beer
2 |Ed |2 |Cats
2 |Ed |3 |Stock-car racing
3 |Red |6 |Bananarama
BTW: If you want foreign-key support in your database you need to call execSQL
with:
PRAGMA foreign_keys = ON
in your SQLiteOpenHelper#onOpen(SQLiteDatabase db).
Write a query and run with SQLiteDatabase.rawQuery(sql, params).
I'm trying to do something simple here but my knowledge on databases and SQL is rusty at best.
I'm was following a tutorial here and am now trying to make my own joined table.
To explain a bit more simply, Profiles have widgets, widgets can be of multiple types.
The widget table contains an id, a name and a string widget_type. For each widget type, there will be another table for that widget_type.
So
Profile
|
|
|
Widget
|
|------------------|--------------------|
Widget1 Widget2 Widget3
The part I'm having trouble with is sharing the Id's among the widgets so that they are unique across all 3 widget tables. Heres the SQL I have below but I'm not entirely sure what I'm trying to do is called or if it can be done from within SQLite
private static final String PROFILE_DATABASE_CREATE = "create table "
+ TABLE_PROFILES + "( " + COLUMN_ID
+ " integer primary key autoincrement, " + PROFILE_COLUMN_NAME
+ " text not null);";
// Widget creation SQL statement
private static final String WIDGET_DATABASE_CREATE = "create table "
+ TABLE_WIDGETS + "(" + COLUMN_ID +"integer primary key autoincrement" + WIDGET_COLUMN_TYPE +"text not null";
Urk. Hard to do this so that the IDs in Widget1 are different from the IDs in Widget2.
A more simple way is to collapse all the tables together. The Contacts Provider that backs the People application does this. Have one table containing the data for all three widget types. Differentiate a row for a particular widget type with a unique MIME type. Add a widget by adding it to the table with the _ID value of the profile it belongs to, the MIME type for its widget type, and its data.
The trick is to give this "generic widget" table the maximum number of columns you'd need for any type of widget. Provide some columns that are the same for any widget, and then some generic columns (say DATA1 through DATA5) whose contents vary according to the type of widget. Then assign type-specific constants for each widget type
For example, for the Widget table you'd create these column name constants
private static final String _ID = "_ID";
private static final String WIDGET_NAME = "name";
private static final String WIDGET_TYPE = "MIMEtype";
then
private static final String WIDGET1_TYPE = "vnd.example.com/widget1";
private static final String WIDGET2_TYPE = "vnd.example.com/widget2";
private static final String WIDGET3_TYPE = "vnd.example.com/widget3";
and
private static final String SOME_WIDGET1_COLUMN = "DATA1";
private static final String SOME_OTHER_WIDGET2_COLUMN = "DATA2";
etc.
It really doesn't matter if you retrieve a row of MIME type "vnd.example.com/widget1" and then access the cursor using "SOME_OTHER_WIDGET2_COLUMN", but it's easier to keep track of what's going on if you use the Widget1 constants on Widget1 cursors, etc.
If you've ever wondered what all the contract classes for android.provider do, well, this is it.
i am trying to query my database so that it returns only rows with a specific value in a certain column.but when i run it, it still returns all the rows. please take a look at the code and see if i have done it incorrectly. I am trying to query for the string in the PRIORITY column. i want to display those specific rows in a listview. Thank you.
private static final String DATABASE_NAME = "MemoData.db";
private static final int DATABASE_VERSION = 1;
public static final String DATABASE_TABLE = "Places";
public static final String KEY_ID = "_id";
public static final String NAME = "Title";
public static final String CATEGORY = "category";
public static final String PRIORITY = "priority";
private static final String TAG = "DBAdapter";
private static final String DATABASE_CREATE = "create table Places (_id integer primary key autoincrement, Title text, category text, priority text);";
public Cursor priorityData(){
String[] resultColumns = new String[] {KEY_ID,NAME,CATEGORY,PRIORITY };
String[] condition = {"High"};
Cursor cursor = db.query(DATABASE_TABLE, resultColumns, KEY_ID + "=" + "?", condition, null, null, null);
if(cursor.moveToNext()){
return cursor;
}
return cursor;
}
The values for priority columns can be "Low", "Medium" or "High". i am trying to query the database to return rows whose values are set as "High" in the PRIORITY column.
I am trying to query for the string in the PRIORITY column...
So your filter should be
PRIORITY + " = ?"
instead of
KEY_ID + "=" + "?"
Also it's not a good idea to have a text column to hold values from a limited set of possibilities that you are then filtering and your last if makes no sense.
I think he meant that you should use ENUM type to your PRIORITY variable, because it has limited set of possibilities.
So it should looks something like this:
priority ENUM('LOW','MEDIUM','HIGH') NOT NULL DEFAULT 'MEDIUM'