change sqlite table column to be unique [duplicate] - android

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

Related

How to delete the contents of an entire column from an external database?

I read data from an external database and I want to delete the contents of an entire column from it.
How can I achieve this?
If you are working on the Sqlite database then add this in your Database Class File.
From: http://www.sqlite.org/faq.html:
(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. If you want to make more complex changes in the structure of a table, you will have to recreate the table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from the temporary 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;
Simply UPDATE the column value with its default value (i.e. '' for a text column, 0 for an integer, NULL for a nullable, ...), specifying no condition (no WHERE clause).
This will replace ALL the values on that column with a default value.

conflict that may occur when adding column to a table

Currently i have a database in android sqllite with many tables of the following column, column A and column B.
Now i am required to have table of column A , column B and column C for subsequent future table created in database. It is alright for me to keep old table of column A and B without changing anything.
so i have the following concern.
1 Let say i have the following code
rssiDB.execSQL("CREATE TABLE IF NOT EXISTS " + rssiTableName + " (ssid VARCHAR, bssid VARCHAR , rssi INTEGER )" );
What is the meaning of if not exists. If i am trying to create a table with a table name that already exists but different number of column, will the creation of table be successful? What will happen actually.
for example i have this table of the table name testing20 with column value of a743954759 , -40
and now i want to create a table of the table name testing20 with column value of peterwifi,a7954759 , -60
will the above code create a table with the same name but different number of column.
2 In a database, is it allowed for database to have many table of different column or is it compulsory for database to have every table to have the exact number of column or column name.
Let say i have a database with one table of table name testing1 with column A and column B. can i now add a table with table name testing2 with column A, column B and column C to the database.
I know i can try this out to find out myself. However i am afraid that it will affect my existing table if i try it out.
Hope someone can answer my question. Thank you
Table are unique objects in database, so you can define two tables with the same name. But you can alter existing tables and add new columns using ALTER TABLE function on your onUpgrade() method, like this :
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// If you need to add a column
if (newVersion > oldVersion) {
db.execSQL("ALTER TABLE foo ADD COLUMN new_column INTEGER DEFAULT 0");
}
}
Refere to this question How to add new Column to Android SQLite Database? for more info

Add unique column to already exist sqlite 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.)

How do I get "insert or update" behaviour without using CONFLICT_REPLACE?

My Android app is using an SQLite FTS3 table to provide full text search. I'm using insertWithOnConflict with CONFLICT_REPLACE to update my database, inserting a new row if need be or updating an existing row if it's present.
I was very surprised to find that my table ended up containing duplicate rows — but it looks like this is a documented "feature" of SQLite's FTS modules:
From the SQLite FTS3 and FTS4 Extensions page:
Datatypes and column constraints are specified along with each column.
These are completely ignored by FTS and SQLite.
It's pretty easy to replicate the duplication from the command line:
sqlite> CREATE VIRTUAL TABLE test_duplicates USING FTS3
...> (id INTEGER PRIMARY KEY, name TEXT);
sqlite> INSERT INTO test_duplicates (id, name) VALUES (1, "George");
sqlite> INSERT INTO test_duplicates (id, name) VALUES (1, "George");
sqlite> INSERT OR REPLACE INTO test_duplicates (id, name) VALUES (1, "George");
sqlite> SELECT * FROM test_duplicates;
1|George
1|George
1|George
sqlite>
My question is: what's the best (simplest, most robust) way to replicate the behaviour of CONFLICT_REPLACE?
My ideas at the moment are either to (A) do a SELECT, then an UPDATE or INSERT based on the result or (B) blindly try DELETE the existing row (which may or may not be present) and then INSERT.
refering to the fts document, i found this paragraph:
... each FTS table has a "rowid" column. The rowid of an FTS table behaves in the same way as the rowid column of an ordinary SQLite table, except that the values stored in the rowid column of an FTS table remain unchanged if the database is rebuilt using the VACUUM command. For FTS tables, "docid" is allowed as an alias along with the usual "rowid", "oid" and "oid" identifiers. Attempting to insert or update a row with a docid value that already exists in the table is an error, just as it would be with an ordinary SQLite table.
which means you could use the built-in docid column as your primary key and let the fts table apply it's constraint on it.
I have the same problem. I found out that when we CREATE VIRTUAL TABLE test_duplicates USING FTS3 it will create a column named rowid and it's primary key of this table so that we just need using rowid instead id that will work correctly.
If you change:
INSERT INTO test_duplicates (id, name) VALUES (1, "George");
to:
INSERT INTO test_duplicates (rowid, id, name) VALUES (1, 1, "George");
INSERT INTO test_duplicates (rowid, id, name) VALUES (2, 2, "George");
i won't take credit for this. but i can't find the original link i got this from.
you do a query, then:
if (cursor.moveToFirst()) {
// record exists
} else {
// record not found
I use the following query for INSERT OR REPLACE
INSERT OR REPLACE INTO test_duplicates (`rowid`, `name`) VALUES
((SELECT `rowid` FROM test_duplicates WHERE `name` = "George" LIMIT 1), "George")
And it works. But in this case, you can't supply the rowid. rowid will be handled by Database itself.

How do I delete column from sqlite table in android?

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

Categories

Resources