I am working with SQLite database and I am facing a problem when comes to insert/remove column of a table.
Simply, I am trying to update the columns of a table called 'Category' in my database.
ALTER TABLE Category RENAME TO Category1;
CREATE TABLE Category (c_id INTEGER PRIMARY KEY AUTOINCREMENT, c_name TEXT, c_prefix TEXT, INT c_parent);
INSERT INTO Category (c_name, c_parent) SELECT name, parent FROM Category1;
but I am getting:
Error: table Category has no column named c_parent
I've also tried to DROP Category table and re-create it (as I know sometimes keeps reference to the old one) without any luck.
All, tables' and columns' names are correct (double-checked).
Any idea how I can make SQLite recognise the new table as the 'Category' one?
You've transposed the type and column name in the last column of your create table, viz
CREATE TABLE Category
...
c_parent INT )
Once you've confirmed all your data is safely across, you can DROP TABLE Category1
Your CREATE statement has the type & name of the c_parent column reversed.
Related
I want to add an extra unique constraint to an existing table. This and other answers say it's not possible with sqlite, and suggest creating an unique index:
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
This seems to work. However, I'm having trouble with UPSERTs:
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';
This gives an error:
ON CONFLICT cause does not match any PRIMARY KEY or UNIQUE constraint
Is there any way I could adapt the ON CONFLICT clause of the statement above to work with the new "constraint"?
I tried using new_unique_index, to no avail. If it's impossible, is there any alternative to creating a new table with the new unique constraint and copying the values from the old table into the new one with NULL for the new constraint column? This would be burdensome. I imagine I could create a new table with all of the former's columns, except the old uniques, plus the new unique, and link them somehow, but it sounds messy and I have no idea how to proceed.
Minimum reproducible example:
CREATE TABLE example (foo TEXT, old_unique TEXT, UNIQUE(old_unique));
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';
Is there any way I could adapt the ON CONFLICT clause of the statement above to work with the new "constraint"?
(old_unique, new_unique) is a not a possible constraint target as there is no index that combines both columns, each is an individual constraint (so you could use one or the other, as my understanding is that you are limited to a single UPSERT clause and a single conflict target).
If instead of :-
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
You used
CREATE UNIQUE INDEX new_unique_index ON example(old_unique,new_unique);
Then the following will work :-
INSERT INTO example (foo,old_unique,new_unique) VALUES('foo','old','new') ON CONFLICT (old_unique,new_unique) DO UPDATE SET foo = 'foo';
(well at least not be rejected due to no covering primary key or index for the given conflict target).
If it's impossible, is there any alternative to creating a new table with the new unique constraint and copying the values from the old table into the new one with NULL for the new constraint column? This would be burdensome.
It's not really burdensome e.g. you could use :-
CREATE TABLE IF NOT EXISTS temp_example (foo, old_unique,new_unique, UNIQUE(old_unique,new_unique));
INSERT INTO temp_example SELECT *,null FROM example;
ALTER TABLE example RENAME TO old_example;
ALTER TABLE temp_example RENAME TO example;
DROP TABLE If EXISTS old_example;
i.e. as you are adding a column and it will be the last column then there is no need to code column names.
I want to copy the rows of a table OLD into another table NEW.
INSERT INTO NEW
SELECT date, kind, id, product, version, quantity FROM OLD;
The table OLD has a column kind which is VARCHAR and contains words like insert, extract, delete. In the NEW table this column is an INTEGER. Is there a way to say that if you find delete insert 1, if you find extract insert 2 etc.. ?
This should work for you,
INSERT INTO Destination SELECT * FROM Source;
See SQL As Understood By SQLite: INSERT for a formal definition.
You can use a CASE statement to replace the string labels with integers:
INSERT INTO NEW
SELECT date,
CASE WHEN kind = 'delete' THEN 1
WHEN kind = 'extract' THEN 2
ELSE ...
END,
product,
version,
quantity
FROM OLD;
This assumes that the columns line up correctly, and all the other column types match.
Hi In my application I am using SQLITE database,
I want to add multiple column in table,
If i am adding one column that work fine,
I am using ALTER table for add new column,
With this i am able to update one column,
ALTER TABLE "main"."tblCredit" ADD COLUMN "CardDetail" VARCHAR
But How can i add multiple column in tblCredit table.
Use repeated calls to ALTER TABLE.
You should not have to do this too often anyway.
IN DB2
with the help of alter command add multiple column in table
ALTER TABLE TABLE_NAME ADD COLUMN F_NAME VARCHAR(30)
ADD COLUMN L_NAME VARCHAR(30)
ADD COLUMN ROLL_NO INTEGER
ADD COLUMN MOBILE_NUMBER VARCHAR(12);
This is the schema of my table:
create table LPCG(ID integer primary key, PCG text, Desc text, test text);
I wish to drop the column "test", and hence use the command:
alter table LPCG drop column test;
This is the error message I get:
Error: near "drop": syntax error
Can someone please help me correct my error?
An additional question is: I understand that ID is the primary key attribute. Would I be able to drop that column? If not, is there a workaround which anyone has used?
Thanks in advance for any help.
Up to version 3.35, SQLite did not support ALTER TABLE DROP COLUMN statements. You could only rename table, or add columns.
If you want to drop a column, your best option was to create a new table without the column, and to drop the old table in order to rename the new one.
As of now, ALTER TABLE support is still limited but includes dropping a column, under conditions.
I have an SQLite table that I need to sort. I am familiar with the ORDER BY command but this is not what I am trying to accomplish. I need the entire table sorted within the database.
Explanation:
My table uses a column called rowed which sets the order of the table (a key?). I need to sort the table by another column called name and then re-assign rowid numbers in alphabetical order according to name. Can this be done?
Assuming you created your original table like so:
CREATE TABLE my_table (rowid INTEGER PRIMARY KEY, name TEXT, somedata TEXT) ;
You can create another sorted table like so:
CREATE TABLE my_ordered_table (rowid INTEGER PRIMARY KEY, name TEXT, somedata TEXT) ;
INSERT INTO my_ordered_table (name, somedata) SELECT name,somedata FROM my_table
ORDER BY name ;
And if you then want to replace the original table:
DROP TABLE my_table ;
ALTER TABLE my_ordered_table RENAME TO my_table;
I think this issue relates to wanting the primary key to mean something. Avoid that trap. Choose an arbitrarily generated primary key that uniquely identifies a row of data and has no other meaning. Otherwise you will eventually run into the problem of wanting to alter the primary key values to preserve the meaning.
For a good explanation of why you should rely on ORDER BY to retrieve the data in the desired order instead of assuming the data will otherwise appear in a sequence determined by the primary key see Cruachan's answer to a similar question