SQLite Copy Table Content from one Table to another Table and Update - sqlite

I have two SQLite files, each of them has one table and the same table design. One Column is set as Primary Key. I want to copy all data from ItemsB into ItemsA. All data should be updated. The ItemsB Table is the newer one.
I've tried:
ATTACH DATABASE ItemsB AS ItemsB;
INSERT INTO ItemsA.PMItem (ItemID,VarID,Name1) SELECT ItemID,VarID,Name1 FROM ItemsB.PMItem;
Obviously this can't work due the Primary Key (which is the column VarID).
Then I tried it with ON CONFLICT:
ON CONFLICT (VarID) DO UPDATE SET Name1=excluded.Name1
But this won't work either.
Example Table:
CREATE TABLE PMItem (
ItemID INTEGER,
VarID INTEGER PRIMARY KEY,
Name1 TEXT
);

You need a WHERE clause with an always true condition, to overcome the ambiguity that is raised when ON CONFLICT is used after a SELECT statement:
INSERT INTO PMItem (ItemID,VarID,Name1)
SELECT ItemID,VarID,Name1
FROM ItemsB.PMItem
WHERE 1
ON CONFLICT(VarID) DO UPDATE
SET Name1 = EXCLUDED.Name1;

Related

Sqlite FOREIGN KEY constraint failed during add column

My issue is that I am getting a foreign key constraint error when I try to add a column to a table. Not a row, a column!
My table is called Screens. It has two tables with foreign key dependencies. They are called Topic and ScreenTypes. Both tables are very small and they only have 2 columns each (id and name). The Screens table contains the columns TopicId and ScreenTypeId plus a couple of other columns. All three table have primary indexes. Everything has been working fine for the past few weeks.
Then, I tried to add a new column to the Screens table called ScreenNumber. The new column is numeric and has no restrictions whatsoever. But, when I tried to commit the change to the schema, I got a foreign key constraint error.
I thought I would get around it by removing the foreign key constraint, adding the column and then adding the foreign key constraint back. But, when I tried to remove the foreign key constraint, I got another foreign key constraint error.
Any help would be greatly appreciated! I have no idea what is causing this and I am past my deadline for this project.
My table is called Screens. It has two tables with foreign key
dependencies. They are called Topic and ScreenTypes. Both tables are
very small and they only have 2 columns each (id and name). The
Screens table contains the columns TopicId and ScreenTypeId plus a
couple of other columns. All three table have primary indexes.
Everything has been working fine for the past few weeks.
From the above and your comments then this appears to create the Screens Table, the Topics Table and the ScreenTypes table and additionally populate the tables with some data:-
DROP TABLE IF EXISTS Screens;
CREATE TABLE IF NOT EXISTS Screens (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
Video TEXT NOT NULL,
TopicId INTEGER NOT NULL,
Instructions TEXT,
ScreenTypeId INTEGER,
SortOrder INTEGER DEFAULT (10),
Image TEXT,
NewColumn INTEGER,
FOREIGN KEY (TopicId) REFERENCES Topics (id),
FOREIGN KEY (ScreenTypeId) REFERENCES ScreenTypes (id)
)
;
DROP TABLE IF EXISTS Topics;
CREATE TABLE IF NOT EXISTS Topics (ID INTEGER PRIMARY KEY, name TEXT);
DROP TABLE IF EXISTS ScreenTypes;
CREATE TABLE IF NOT EXISTS ScreenTypes (ID INTEGER PRIMARY KEY, name TEXT);
INSERT INTO Topics (name) VALUES ('Topic1'),('Topic2'),('Topic3'),('Topic4');
INSERT INTO ScreenTypes (name) VALUES ('SreenType1'),('ScreenType2'),('ScreenType3'),('ScreenType4');
INSERT INTO Screens (Video,TopicId,Instructions,ScreenTypeId,Image,NewColumn) VALUES
('Video1',2,'do this 001',3,'Image1','blah'),
('Video2',2,'do this 002',3,'Image2','blah'),
('Video3',1,'do this 002',1,'Image3','blah'),
('Video4',3,'do this 004',4,'Image4','blah'),
('Video5',4,'do this 005',1,'Image5','blah')
;
Then, I tried to add a new column to the Screens table called
ScreenNumber. The new column is numeric and has no restrictions
whatsoever. But, when I tried to commit the change to the schema, I
got a foreign key constraint error.
The following works :-
ALTER TABLE Screens ADD COLUMN ScreenNumber INTEGER DEFAULT 100;
as per :-
ALTER TABLE Screens ADD COLUMN ScreenNumber INTEGER DEFAULT 100
OK
Time: 0.083s
and then using the following
SELECT * FROM Screens;
The result is :-
As can be seen, there were no FK constraint conflicts and the column has been added and the default value of 100 applied.
I suspect that your issues with FK Constraints is that you are progressively try to correct issues.
First (at a guess) you try altering (renaming) the Screens table but can't because of the Fk constraint conflicts with the Fields table. You then try altering the Fields table but still you get FK conflicts, due to :-
If an "ALTER TABLE ... RENAME TO" command is used to rename a table that is the parent table of one or more foreign key constraints, the definitions of the foreign key constraints are modified to refer to the parent table by its new name. The text of the child CREATE TABLE statement or statements stored in the sqlite_master table are modified to reflect the new parent table name.
SQLite Foreign Key Support - 5. CREATE, ALTER and DROP TABLE commands
Of course, if acccording to your description, you only want to add the column then the ALTER TABLE Screens ADD COLUMN ScreenNumber INTEGER (with default value if wanted) works without the need to rename tables.

SQLite Insert into a table with one column that is auto incrament

This should be an easy one. I need the SQL to insert into a table that has only one column and it is and autoincrement field.
Similar to this post but SQLite (I am new to SQLite).
Inserting rows into a table with one IDENTITY column only
create table ConnectorIDs
(
ID integer primary key AUTOINCREMENT
);
--none of the following work
INSERT INTO ConnectorIDs VALUES(DEFAULT);
INSERT ConnectorIDs DEFAULT VALUES;
Yes this is strange and if you care here is the reason, if you want to tell me a better way. I have several different item tables that all can have many-to-many links between them but sparse. Instead of having n! bridge tables, or one bridge table with a "Type" that I can't guarantee truly maps to the correct table. I will have one ConnectorID table and each item with have a connectorID key. Then I can have one bridge table.
Insert a null value:
INSERT INTO ConnectorIDs VALUES(NULL);
From the docs:
If no ROWID is specified on the insert, or if the specified ROWID has a value of NULL, then an appropriate ROWID is created automatically.

SQLlite: strange "Abort due to constraint violation"

I'm trying to rename a column of a table. I have a lot of tables with the word "couleur" and I renamed "manually" to "bulle".
I've successfully renamed main_groupecouleurs to main_groupebulles. Now i'm working on main_groupe. I'm trying to rename groupe_couleurs_id to groupe_bulles_id
The SQL is quite self-explaining:
BEGIN TRANSACTION;
DROP INDEX main_groupe_fc5cee5b;
CREATE TABLE main_groupe7e12
(
id INTEGER PRIMARY KEY NOT NULL,
description TEXT NOT NULL,
exemple TEXT,
groupe_bulles_id INTEGER DEFAULT NULL,
reference TEXT,
FOREIGN KEY (groupe_bulles_id) REFERENCES main_groupebulles(id)
DEFERRABLE INITIALLY DEFERRED
);
CREATE UNIQUE INDEX main_groupe_fc5cee5b ON main_groupe7e12 (groupe_bulles_id);
INSERT INTO main_groupe7e12(id, description, exemple, groupe_bulles_id, reference)
SELECT id, description, exemple, groupe_couleurs_id, reference
FROM main_groupe;
DROP TABLE main_groupe;
ALTER TABLE main_groupe7e12 RENAME TO main_groupe;
COMMIT;
When I run it, I get:
[SQLITE_CONSTRAINT] Abort due to constraint violation
(UNIQUE constraint failed: main_groupe7e12.groupe_bulles_id)
This means (I think I'm wrong here but I dont know what I'm missing) that it tries to insert some groupe_couleurs_id that are not in the referring table (= main_groupebulles). Thus I tried to see in the original table the problem:
SELECT * FROM main_groupe WHERE groupe_couleurs_id NOT IN (
SELECT id FROM main_groupebulles
);
I got no rows! What am I missing?
You have an UNIQUE index on your groupe_bulles_id column but based on the comments, there are a lot of valid duplicate values for that column coming from main_groupe.groupe_couleus_id and that causes the constraint violation.
Since having duplicate values is what you want, remove the UNIQUE from the CREATE UNIQUE INDEX ....

Primary key error when copying table data in SQLLite

I've created a second table that I want to copy data from a first table to.
table2 has the same structure as table1, only some of it's columns are COLLATE NOCASE. Apart from that and the table names, the tables are identical.
Each table has the PK:
hID INTEGER PRIMARY KEY AUTOINCREMENT
When copying, I get an error on the following query:
INSERT INTO table2 SELECT * FROM table1
The error:
PRIMARY KEY must be unique
I'm assuming the original data is unique, as it's always had the PK.
I want to preserve the original hID's when copying ie I don't want new hID's set for the old data being copied.
In MySQL, I'd normally apply a PK to the second table AFTER copying over the data, but I think that's not allowed in SQLLite.
Can anyone explain the error in my ways?

Can I alter a column in an sqlite table to AUTOINCREMENT after creation?

Can I make a field AUTOINCREMENT after made a table? For example, if you create a table like this:
create table person(id integer primary key, name text);
Then later on realise it needs to auto increment. How do I fix it, ie in MySQL you can do:
alter table person modify column id integer auto_increment
Is table creation the only opportunity to make a column AUTOINCREMENT?
You can dump the content to a new table:
CREATE TABLE failed_banks_id (id integer primary key autoincrement, name text, city text, state text, zip integer, acquired_by text, close_date date, updated_date date);
INSERT INTO failed_banks_id(name, city, state, zip, acquired_by,close_date, updated_date)
SELECT name, city, state, zip, acquired_by,close_date, updated_date
FROM failed_banks;
And rename the table:
DROP TABLE failed_banks;
ALTER TABLE failed_banks_id RENAME TO failed_banks;
Background:
The new key will be unique over all
keys currently in the table, but it
might overlap with keys that have been
previously deleted from the table. To
create keys that are unique over the
lifetime of the table, add the
AUTOINCREMENT keyword to the INTEGER
PRIMARY KEY declaration.
http://www.sqlite.org/faq.html#q1
SQLite limitations:
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.
http://www.sqlite.org/lang_altertable.html
Hack seems to exist:
It appears that you can set
PRAGMA writable_schema=ON;
Then do a manual UPDATE of the
sqlite_master table to insert an "id
INTEGER PRIMARY KEY" into the SQL for
the table definition. I tried it and
it seems to work. But it is
dangerous. If you mess up, you
corrupt the database file.
http://www.mail-archive.com/sqlite-users#sqlite.org/msg26987.html
From the SQLite Faq
Short answer: A column declared INTEGER PRIMARY KEY will autoincrement
So when you create the table, declare the column as INTEGER PRIMARY KEY and the column will autoincrement with each new insert.
Or you use the SQL statment ALTER to change the column type to an INTEGER PRIMARY KEY after the fact, but if your creating the tables yourself, it's best to do it in the initial creation statement.
Simplest way — Just export and re-import
It is possible, and relatively easy. Export the database as an sql file. Alter the SQL file and re-import:
sqlite3 mydata.db .dump > /tmp/backup.sql
vi /tmp/backup.sql
mv mydata.db mydata.db.old
sqlite3 mydata.db
sqlite>.read /tmp/backup.sql
You can do it with SQLite Expert Personal 4:
1) Select the table and then go to "Design" tab > "Columns" tab.
2) Click "Add" and select the new column name, and type INTEGER and Not Null > Ok.
3) Go to "Primary Key" tab in "Desgin tab". Click "Add" and select the column you just created. Check the "Autoincrement" box.
4) Click "Apply" on the right bottom part of the window.
If you go back to the "Data" tab, you will see your new column with the autogenerated numbers in it.
While the Sqlite site gives you an example how to do it with a table with only a three fields, it gets nasty with one of 30 fields. Given you have a table called OldTable with many fields, the first of which is "ID" filled with integers.
Make a copy of your database for backup.
Using the command program dot commands,
.output Oldtable.txt
.dump Oldtable
Drop Table Oldtable;
Open Oldtable.txt in Microsoft Word or a grep like text editor. Find and Replace your Integer field elements with NULL.(You may need to adjust this to fit your fields). Edit the Create Table line so the field that was defined as Integer is now INTEGER PRIMARY KEY AUTOINCREMENT.
Save as NewTable.txt
Back in the command program dot
.read NewTable.txt
Done.
ID is now autoincrement.
Yes
Do you have phpmyadmin installed? I believe if you go to the 'structure' tab and look along the right columnn (where the field types are listed) - I think you can change a setting there to make it autoincrement. There is also a SQL query that will do the same thing.
You cannot alter columns on a SQLite table after it has been created. You also cannot alter a table to add an integer primary key to it.
You have to add the integer primary key when you create the table.
Yes, you can make a column which is autoincrement. Modify the table and add a column. Keep in mind that it is of type INTEGER Primary Key.
you can alter the table, altering the column definition
Simple Answer is as below,
CREATE TABLE [TEST] (
[ID] INTEGER PRIMARY KEY AUTOINCREMENT,
[NAME] VARCHAR(100));
and you are done.

Resources