SQLite create dynamic table (or view?) - java

I have 3 tables:
Table.Keys, Table.Tags, Table.Values
Table.Keys create table statement:
createTableStatement = "CREATE TABLE " + Tables.KEYS + "("
+ KeysColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ KeysColumns.KEY + " TEXT NOT NULL,"
+ "UNIQUE ("
+ KeysColumns.KEY
+ ") ON CONFLICT IGNORE"
+ ");";
execSQL(sqLiteDatabase, createTableStatement);
Table.Tags create table statement:
createTableStatement = "CREATE TABLE " + Tables.TAGS + " ("
+ TagsColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ TagsColumns.NAME + " TEXT NOT NULL,"
+ "UNIQUE ("
+ TagsColumns.NAME
+ ") ON CONFLICT IGNORE"
+ ");";
execSQL(sqLiteDatabase, createTableStatement);
Table.Value create table statement:
createTableStatement = "CREATE TABLE " + Tables.VALUES + " ("
+ ValuesColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
+ ValuesColumns.KEY_ID + " TEXT NOT NULL,"
+ ValuesColumns.TAG_ID + " TEXT NOT NULL,"
+ ValuesColumns.VALUE + " TEXT NOT NULL,"
+ "UNIQUE ("
+ ValuesColumns.KEY_ID + ", " + ValuesColumns.TAG_ID
+ ") ON CONFLICT REPLACE"
+ ");";
execSQL(sqLiteDatabase, createTableStatement);
If I do the following join:
Tables.KEYS
+ " JOIN " + Tables.VALUES
+ " ON " + Values.KEY_ID + " = " + Keys.column(Keys._ID)
+ " JOIN " + Tables.TAGS
+ " ON " + Values.TAG_ID + " = " + Tags.column(Tags._ID);
I get duplicate rows of course because the result is
KEY | TAG | VALUE
=================
| |
What I would like to accomplish is to query and get a Cursor from table or view with no duplicate rows with the following schema:
KEY | TAG 1 | TAG 2 | ... | TAG n
=================================
| | | |
Not all keys MUST have values for each tag, but all keys CAN have values.
I'm not sure how to accomplish this. I'm not even sure where to start.
In the meantime I have created another table which stores some TAG values that I know will always exist.
But I feel this is inefficient because at any time I could have 'n' number of new TAG values which is why I would like to be able to create a view or table with the schema I listed.

SQLite has no pivot functions; you have to do this in two steps.
First, get all possible tags:
SELECT _id, Name
FROM Tags
ORDER BY Name;
Then, using the returned data, construct a query that looks up each possible tag for each key:
SELECT Key,
(SELECT Value
FROM Values
WHERE Key_ID = Keys._id
AND Tag_ID = 111
) AS Tag_111,
(SELECT Value
FROM Values
WHERE Key_ID = Keys._id
AND Tag_ID = 222
) AS Tag_222,
...
FROM Keys;

Related

How to retrieve Real type data from specific cell in android sqlite?

In this table, I want to retrieve the value 55.2 in a variable.
This value is at row 5 (ID=5) and in the column 'Weight' of type REAL.
I can already get the desired row number which is stored in 'lastID' and I know that my data is in the column 'Weight'. So I have my X and my Y in the table.
I also know the sqlite command to retrieve the 55.2 in my cursor:
Cursor cursor2 = db.rawQuery("SELECT Weight FROM <MYTABLE> WHERE ID=" + lastID, null);
Double lastWeight = cursor2.getDouble(0); //This line is wrong, I need the help here!
But I can't get the 55.2 value I am looking for in my variable lastWeight from cursor2.
Any idea?
Addendum
Here the create table:
String CREATE_TABLE2 = "CREATE TABLE " + <MYTABLE> + " (" + UID2 + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COL_2 + " TEXT," + COL_3 + " TEXT," + COL_4 + " REAL," + COL_5 + " REAL);";
db.execSQL(CREATE_TABLE2);
After the execution of this line:
Cursor cursor2 = db.rawQuery("SELECT Weight FROM <MYTABLE> WHERE ID=" + lastID, null);
you get the results in cursor2.
A Cursor instance like cursor2 is used to loop through its rows and to do so you must first place its index at the 1st row by moveToFirst():
if (cursor2.moveToFirst()) {
Double lastWeight = cursor2.getDouble(0);
........................................
}
The if statement is necessary just in case the cursor does not contain any rows.

Getting Exception With DB2 Auto Increment

I have created the following table:
"CREATE TABLE ParsonCollection "
+ "(id integer not null GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),"
+ "name varchar(20),"
+ "eye varchar(20),"
+ "hair varchar(20),"
+ "height varchar(20),"
+ "weight varchar(20),"
+ "PRIMARY KEY (id))";
I am then trying to insert into the table and this is where I am running into issues. When I try to alter the "id" column, I get an error saying "java.sql.SQLSyntaxErrorException: Attempt to modify an identity column 'ID'. " Here is what the insert statement looks like:
"insert into ParsonCollection values(" + q_surround(Name) + ","
+ q_surround(Eye) + "," + q_surround(Hair) + "," + q_surround(Height) + "," + q_surround(Weight) + ",1" + ")";
However, when I take away the field that is inserting into "id", I get the following error: "java.sql.SQLSyntaxErrorException: The number of values assigned is not the same as the number of specified or implied columns." Here is what this insert statement looks like:
"insert into ParsonCollection values(" + q_surround(Name) + ","
+ q_surround(Eye) + "," + q_surround(Hair) + "," + q_surround(Height) + "," + q_surround(Weight) + ")";
How do I get past this? It seems that when I solve one exception, the other one pops up and vice versa. Thanks.
You can't assign to an identity column. Since you cannot pass all values for insert, you need to enumerate the columns (omitting the identity column):
"insert into ParsonCollection (
name,
eye,
hair,
height
weight
) values("
+ q_surround(Name)
+ "," + q_surround(Eye)
+ "," + q_surround(Hair)
+ "," + q_surround(Height)
+ "," + q_surround(Weight)
+ ")";
Side note: your code is opened to SQL injection. You should seriously consider using prepared statements and bind parameters instead of concatenating the query string.
Out of interest, another solution would be to make the identity column IMPLICITLY HIDDEN

Sqlite exception near "FOREIGN"?

String CREATE_SUBCATEGORY_TABLE = "CREATE TABLE " + TABLE_SUBCATEGORY_LIST+ "("
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," + KEY_NAME + " TEXT,"
+ KEY_DESC + " TEXT,"+ KEY_CATEGORY_ID + " INTEGER,"
+ KEY_CONTENT1+" TEXT,"+ KEY_CONTENTTYPE1 + " TEXT,"
+ KEY_CONTENT2+" TEXT,"+ KEY_CONTENTTYPE2 + " TEXT,"
+ KEY_CONTENT3+" TEXT,"+ KEY_CONTENTTYPE3 + " TEXT,"
+ KEY_CONTENT4+" TEXT,"+ KEY_CONTENTTYPE4 + " TEXT,"
+ KEY_CONTENT5+" TEXT,"+ KEY_CONTENTTYPE5 + " TEXT,"
+ KEY_CONTENT6+" TEXT,"+ KEY_CONTENTTYPE6 + " TEXT,"
+ KEY_ORDERID+" INTEGER,"+ KEY_STATUS+" TEXT,"
+ KEY_UPDATED+" TEXT, FOREIGN KEY ("+KEY_CATEGORY_ID+") REFERENCES "+CAT_TABLE+"("+KEY_CATEGORY_ID+")";
I am getting the following error now:-
android.database.sqlite.SQLiteException: near ")": syntax error (code 1): , while compiling: CREATE TABLE subcategory_list(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,subcategory_name TEXT,subcategory_shdesc TEXT,category_id INTEGER,content1 TEXT,content_type1 TEXT,content2 TEXT,content_type2 TEXT,content3 TEXT,content_type3 TEXT,content4 TEXT,content_type4 TEXT,content5 TEXT,content_type5 TEXT,content6 TEXT,content_type6 TEXT,order_id INTEGER,status TEXT,updated TEXT, FOREIGN KEY (category_id) REFERENCES category_list(category_id)
Can anyone point out my mistake. Any help or suggestions are appreciated. Thank you.
Just fix some typos in the last line:
+ KEY_UPDATED + " TEXT," //added , and space
+" FOREIGN KEY (" + KEY_CATEGORY_ID + ") REFERENCES "
+ CAT_TABLE + "("+KEY_CATEGORY_ID+"))"; //added "CREATE TABLE closing parenthesis"
Add a Space before and a comma after "TEXT" in the last line.
You also have to close the last bracket.
Your last line would look correctly like this:
+ KEY_UPDATED+" TEXT," +" FOREIGN KEY ("+KEY_CATEGORY_ID+") REFERENCES "+CAT_TABLE+"("+KEY_CATEGORY_ID+"))";
You can also omit the " + " between TEXT and FOREIGN KEY, because you're just joining two strings.
+ KEY_UPDATED+" TEXT, FOREIGN KEY ("+KEY_CATEGORY_ID+") REFERENCES "+CAT_TABLE+"("+KEY_CATEGORY_ID+"))";

No such column with foreign key

I want to connect to tables in my database with different ID's (CustomerID, OrderID). I use the following code to create my foreign key:
FOREIGN KEY("+ COLUMN_ORDER_ID + ") REFERENCES+TABLE_NAME_CUSTOMER + "(" + COLUMN_CUSTOMER_ID + "));";
I'm not posting the complete source code, because my first table works fine and I think the problem is the foreign key.
I filter my data with this method:
public List<Orders> getOrdersByCustomerID() {
List<Orders> orderList = new ArrayList<Orders>();
String query = "select " + COLUMN_ORDER_ID
+ "," + COLUMN_ORDER_NAME
+ "," + COLUMN_SETS
+ "," + COLUMN_REPEATS
+ "," + COLUMN_SECTION
+ " from " + TABLE_NAME_ORDERS
+ " where " + COLUMN_CUSTOMER_ID
+ "=" + COLUMN_ORDER_ID;
db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()) {
do {
Orders orders = new Orders(cursor.getString(0), cursor.getString(1), cursor.getInt(2), cursor.getInt(3), cursor.getString(4));
orderList.add(orders);
} while (cursor.moveToNext());
}
db.close();
return orderList;
}
I get this error message:
06-26 17:11:26.154 10163-10163/com.xxx.xxx.xxx
E/AndroidRuntime: FATAL EXCEPTION: main process: com.xxx.xxx.xxx, PID: 10163
java.lang.RuntimeException: Unable to start activity
android.database.sqlite.SQLiteException: no such column:
customerId(Sqlite code 1): , while compiling: select
orderId,orderName,sets,repeats,section from orders where
customerId=orderId,(OS error - 2:No such file or directory)
I think the connection between this two ids is incorrect, or must I commit the id from my customer table? Any tips? As per my understanding, a Customer can have multiple Orders. That's why I use the foreign key; I hope this is correct.
Edit: I was wrong apparently queries are case-insensitive by default in mysql.
Edit:
In order to create a foreign key both tables must contain the ConsumerId. This allows you the establish a relationship using the foreign key.
Your query has to be changed as wel, after creating the foreign key. It should be something like this
select " + COLUMN_ORDER_IDq
+ "," + COLUMN_ORDER_NAME
+ "," + COLUMN_SETS
+ "," + COLUMN_REPEATS
+ "," + COLUMN_SECTION
+ " from " + TABLE_NAME_ORDERS + "," + TABLE_NAME_CUSTOMERS
+ " where " + TABLE_NAME_ORDERS +"." + COLUMN_CUSTOMER_ID
+ "=" + TABLE_NAME_CUSTOMERS + "." + COLUMN_CUSTOMER_ID

How can I set primary key in particular text field?

My Code here
db.execSQL("create table if not exists data(patient_name varchar,patient_id INTEGER PRIMARY KEY ,patient_phone varchar,patient_mail varchar,patient_age,patient_gender varchar,patient_address varchar,patient_lvd varchar,patient_nvd varchar,patient_notes varchar)");
Try this way,
String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS "
+ DATABASE_TABLE + "("
+ patient_id + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ patient_phone + " TEXT, "
+ patient_name + " TEXT, "
+ patient_phone + " TEXT )";
db.execSQL(CREATE_TABLE);
You can follow SQLite Database Tutorial

Categories