I have a ContentProvider backed by an sqlite table. So to create my table I used
public class H extends SQLiteOpenHelper {
#Override
public void onCreate(SQLiteDatabase sqliteDatabase) {
…// here I defined my original table without constraints
}
}
When originally created, the table had the columns: name, age, height. No Constraints. Nothing.
Now I need to add constraints to the table. So I increased the DATABASE_VERSION, and then in the onCreate String I added UNIQUE(name,age) ON CONFLICT REPLACE.
My question is, what should I do inside the onUpgrade method? Stated more simply: How do I call ALTER TABLE just for adding constraints? My attempt failed
ALTER TABLE myTable ADD UNIQUE(name,age) ON CONFLICT REPLACE
Here is the error message:
Caused by: android.database.sqlite.SQLiteException: near "CONSTRAINT": syntax error (code 1): , while compiling: ALTER TABLE myTable ADD CONSTRAINT UNIQUE(name,age) ON CONFLICT REPLACE
#################################################################
Error Code : 1 (SQLITE_ERROR)
Caused By : SQL(query) error or missing database.
(near "CONSTRAINT": syntax error (code 1): , while compiling: ALTER TABLE myTable ADD CONSTRAINT UNIQUE(name,age) ON CONFLICT REPLACE)
Alter table is rather limited in sqlite. However for your purpose CREATE UNIQUE INDEX works just as well.
Generally there is no difference between creating a unique constraint vs creating a unique index. Refer:
SQLite - Any difference between table-constraint UNIQUE & column-constraint UNIQUE? https://dba.stackexchange.com/questions/144/when-should-i-use-a-unique-constraint-instead-of-a-unique-index
So in your case change your code to use should change the code in your onCreate to use CREATE INDEX syntax instead.
Please be aware that this may still fail if your table already has duplicate entries.
You cannot add a constraint with an ALTER TABLE in SQLite.
Only the RENAME TABLE and ADD COLUMN variants of the ALTER TABLE
command are supported. Other kinds of ALTER TABLE operations such as
DROP COLUMN, ALTER COLUMN, ADD CONSTRAINT, and so forth are omitted.
http://www.sqlite.org/omitted.html
Related
I am migrating a Room database in my Android app. This is the migration code:
static final Migration MIGRATION_1_2 = new Migration(1, 2) {
#Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE item RENAME itemInfoId TO itemId");
}
};
The error message
android.database.sqlite.SQLiteException: near "itemInfoId": syntax error (code 1 SQLITE_ERROR): , while compiling: ALTER TABLE item RENAME itemInfoId TO itemId
I have also tried the SQL of "ALTER TABLE item RENAME COLUMN itemInfoId TO itemId", same error
android.database.sqlite.SQLiteException: near "COLUMN": syntax error (code 1 SQLITE_ERROR): , while compiling: ALTER TABLE item RENAME COLUMN itemInfoId TO itemId
Rename keyword is available in SQLite version 3.25 which is not available for the latest android version. You will have to manually upgrade the table
1. Create item_tmp table with correct column value itemId
CREATE TABLE item_tmp(<column1> <data_type>, itemId <data_type>,.....)
2. Copy the data from item to item_tmp
INSERT INTO item_tmp(<column1>, <column2>,..)
SELECT <column1>, <column1>, ...
FROM item;
3. Drop table item
DROP TABLE item;
4. Rename the item_tmp table
ALTER TABLE item_tmp RENAME TO item;
i have faced same problem while using RENAME keyword in Sqlite.
it gives error in below android 10 device and working perfectly in android 11 and above.
How do I alter column in sqlite?
This is in Postgresql
ALTER TABLE books_book ALTER COLUMN publication_date DROP NOT NULL;
I believe there is no ALTER COLUMN in sqlite at all, only ALTER TABLE is supported.
Any idea? Thanks!
There's no ALTER COLUMN in sqlite.
I believe your only option is to:
Rename the table to a temporary name
Create a new table without the NOT NULL constraint
Copy the content of the old table to the new one
Remove the old table
This other Stackoverflow answer explains the process in details
While it is true that the is no ALTER COLUMN, if you only want to rename the column, drop the NOT NULL constraint, or change the data type, you can use the following set of dangerous commands:
PRAGMA writable_schema = 1;
UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
PRAGMA writable_schema = 0;
You will need to either close and reopen your connection or vacuum the database to reload the changes into the schema.
For example:
Y:\> **sqlite3 booktest**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT
NULL);**
sqlite> **insert into BOOKS VALUES ("NULLTEST",null);**
Error: BOOKS.publication_date may not be NULL
sqlite> **PRAGMA writable_schema = 1;**
sqlite> **UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT
NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';**
sqlite> **PRAGMA writable_schema = 0;**
sqlite> **.q**
Y:\> **sqlite3 booktest**
SQLite version 3.7.4
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> **insert into BOOKS VALUES ("NULLTEST",null);**
sqlite> **.q**
REFERENCES FOLLOW:
pragma writable_schema
When this pragma is on, the SQLITE_MASTER tables in which database can be changed using ordinary UPDATE, INSERT, and DELETE statements. Warning: misuse of this pragma can easily result in a corrupt database file.
[alter table](From http://www.sqlite.org/lang_altertable.html)
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table.
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table. But you can alter table column datatype or other property by the following steps.
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT
For more detail you can refer the link.
CREATE TABLE temp_Table(x,y[,etc]);
INSERT INTO temp_Table SELECT * FROM Table;
DROP TABLE Table;
ALTER TABLE temp_Table RENAME TO Table;
Thanks for helping me to find a definitive method!
ALTER COLUMN does not exist in SQLite.
Only Supported alter operations:
Alter Table Name
Alter Table Column Name
Add New Column
Drop Column
Alex Jasmin's answer shows possible way
Reference:
Sqlite Alter Table
I use SQLite database in Android app, and i want to know how to add a unique column to already created table.
by this i mean that the exist table uniqness determine by 2 values and i want to edit the table uniqueness to be determined by 3 values (the 2 exist and 1 more).
is it possible?
The writable_schema trick does not work for UNIQUE because the internal index would need to be changed.
The only way to make this change is with a temporary copy of the table:
CREATE TABLE NewTable(
[...],
UNIQUE(Col1, Col2, Col3)
);
INSERT INTO NewTable SELECT * FROM MyTable;
DROP TABLE MyTable;
ALTER TABLE NewTable RENAME TO MyTable;
(This should be wrapped in a transaction; Android's onUpdate does this automatically.)
I have a table "Items" with different columns but I didn't asign a name in each column. Now I have different rows in this table and I would like to execute:
ItemsDao.queryBuilder().where().eq(Items.NAME, "computer").query();
But my column doesn't have name. I have tried to update my table with "alter table" but it doesn't work.
AnyBody know how I can add a name of my column without lost my information?
Thank you
Edit:
Sorry, now I understand the question. You are saying that you did not specify a columnName = "..." for each of your fields and you are having problems with QueryBuilder now because of this.
You don't need a columnName to get QueryBuilder to work although it is recommended. You should be able to go back to fields and add a columnName static that matches your existing schema. For example, if the field in the database is "items" then you just add the columnName = "items" to your Java field. I don't believe Sqlite is case sensitive with regards to column names but it would be good to match the case as well.
But you don't need the columnName. If you field name in the database is "items" then you should be able to do:
itemsDao.queryBuilder().where().eq("items", "computer").query();
If you edit your question to show your schema and the exception you are getting from QueryBuilder, I'll be able to respond more specifically.
I believe you should be able to do:
dao.executeRaw("ALTER TABLE `items` ADD COLUMN name VARCHAR;");
That doesn't work for you? There is a section in the ORMLite documentation about updating your schema under Android:
http://ormlite.com/docs/upgrade-schema
To quote from it, you will need to change your database version when you make schema changes and then in your onUpgrade(...) method do something like:
Dao<Account, Integer> dao = getHelper().getAccountDao();
// change the table to add a new column named "age"
dao.executeRaw("ALTER TABLE `account` ADD COLUMN age INTEGER;");
Most likely you will be keying off the database version number do if they have version 1 you do X and Y but if they have version 2 you just do Y. Something like that:
if (oldVersion == 1) {
// we added the age column in version 2
dao.executeRaw("ALTER TABLE `account` ADD COLUMN age INTEGER;");
}
if (oldVersion < 2) {
// we added the weight column in version 3
dao.executeRaw("ALTER TABLE `account` ADD COLUMN weight INTEGER;");
}
You are limited by Sqlite on what you can do with ALTER TABLE. Right now you can only rename a column or add a new column. See the docs for more details.
If you want to change the database, in your SQLiteOpenHelper you should:
change database version
override "onUpgrade" to make the changes you
want
change onCreate method, this way new users will have the good version of your database, not the old one
If there are big structural changes, in onUpgrade you copy the useful information in new database and drop the old database.
Hope it helps:)
I tried deleting a column by using the following
openDB.execSQL("ALTER TABLE favs" + " DROP COLUMN favsCount");
LogCat gives the following message:
11-07 21:18:29.238: ERROR/Database(13952): Failure 1 (near "DROP": syntax error) on 0x34e550 when preparing 'ALTER TABLE favs DROP COLUMN favsCount'.
Is it not possible to delete fields in sqlite for Android?
Sorry, SQLite doesn't support DROP COLUMN:
(11) How do I add or delete columns from an existing table in SQLite.
SQLite has limited ALTER TABLE support that you can use to add a column to the end of a table or to change the name of a table. [...]
For example, suppose you have a table named "t1" with columns names "a", "b", and "c" and that you want to delete column "c" from this table. The following steps illustrate how this could be done:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
So basically, you have to use the "copy, drop table, create new table, copy back" technique to remove a column.
as mu is too short says Sqlite doesn't allow to do an alter table to delete a column. here you can see the alter syntax definition