Innodb foreign key constraints - innodb

I am trying to change the type in two tables of an innoDB. The problem is that the values are a key and a foreign key. When I try to make the change I get the following error
#1025 error on rename
Do I need to drop the foreign keys and then make the changes and then reapply the foreign key?

Since u can use the name to drop the foreign key first and the column then:
ALTER TABLE categories DROP FOREIGN KEY categories_ibfk_1;
ALTER TABLE categories DROP COLUMN assets_id;
To find out which table caused the error you can run
SHOW ENGINE INNODB STATUS\G
and then look at the "LATEST FOREIGN KEY ERROR" section.

Yeah, you have to drop the foreign key. Try SHOW INNODB STATUS to see if there's a more elaborated explanation of what's going on.

Related

Error on adding PRIMARY KEY to existing table [duplicate]

I keep getting an error "Incorrect index name 'f7'" using MySQL and I've narrowed it down to the following:
First I create the table,
CREATE TABLE testTable (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
f7 INTEGER NOT NULL,
FOREIGN KEY (f7) REFERENCES testTable2 (id) ON DELETE CASCADE ON UPDATE CASCADE,
) ENGINE=InnoDB;
And then elsewhere,
ALTER TABLE testTable ADD UNIQUE f7;
This has led me to believe that this has to do with a duplicate index (?) I just can't figure out how to fix it. Many thanks.
Give it a name, so it doesn't conflict with the foreign Key index
ALTER TABLE `testtable` ADD UNIQUE INDEX `foo` (`f7`);
An incorrect index name error is given when you're attempting to create a new index with the same name as an existing index.
In MySQL, when you create a foreign key, as you're doing with FOREIGN KEY (f7) REFERENCES testTable2 (id) ON DELETE CASCADE ON UPDATE CASCADE, an index is auto-created as well. In this case, the name is defaulted to f7.
The foreign key is created as a non-unique index; your second command: ALTER TABLE testTable ADD UNIQUE (f7); will make this index unique - not add a second one.
To verify what indexes already exist on the table, you can use the following:
SHOW INDEXES FROM testTable;
If you're receiving this error, there is likely additional code elsewhere that is attempting to create an index named f7. You can attempt to find it, or change your CREATE TABLE syntax to name the key something different so that it doesn't cause conflicts:
FOREIGN KEY fk_testTable_f7 (f7) REFERENCES testTable2 (id) ON DELETE CASCADE ON UPDATE CASCADE
In this example, I used fk_testTable_f7 and you should now have a non-unique index on the table named fk_testTable_f7. To make it unique, you can use your existing ALTER command as you want the column to be unique - not the foreign key itself.

SQLiteException no such table: main.*_temp

I have a Xamarin.Forms app that uses a SQLite database locally on the device. Here's some sample data structure:
Table x: id, name
Table y: id, name
Table x_y: id, x_id, y_id
Since SQLite doesn't support altering columns, one of the schema updates we sent down in a patch did the following:
Rename table x to x_temp
Create new/updated table x
Insert all data from table x_temp into table x
Drop table if exists x
That seems to work just fine. However, when I'm attempting to run an insert statement on table x_y, I am getting a SQLite exception: "no such table: main.x_temp".
When I look at the SQLite query string while debugging there is no mention of table x_temp whatsoever. So, if I delete the entire database and re-create everything the insert works just fine.
I'm from a MSSQL background, am I not understanding something about SQLite in general? Is the foreign key constraint from table x_y trying to reference x_temp because I renamed the original table (I may have just answered my own question)? If that's the case, surely there is a way around this without having to cascade and re-create every table?
Any input would be appreciated. Thanks!
I believe that your issue may be related to the SQlite version in conjunction with whether or not Foreign Key Support has been turned on.
That is the likliehood is that :-
Is the foreign key constraint from table x_y trying to reference
x_temp because I renamed the original table (I may have just answered
my own question)?
Would be the issue, as you likely have Foreign Key Support turned on as per :-
Prior to version 3.26.0 (2018-12-01), FOREIGN KEY references to a table that is renamed were only edited if the PRAGMA foreign_keys=ON, or in other words if foreign key constraints were begin enforced.
With PRAGMA foreign_keys=OFF, FOREIGN KEY constraints would not be changed when the table that the foreign key referred to (the "parent table") was renamed.
Beginning with version 3.26.0, FOREIGN KEY constraints are always converted when a table is renamed, unless the PRAGMA legacy_alter_table=ON setting is engaged. The following table summaries the difference:
SQL As Understood By SQLite - ALTER TABLE
If that's the case, surely there is a way around this without having
to cascade and re-create every table?
Yes, as the latest version of SQlite on Android is 3.19.0 (I believe), then you can turn Foreign Key support off using the foreign_keys pragma when renaming the table.
Note Foreign Keys cannot be turned off within a transaction.
See SQL As Understood By SQLite - ALTER TABLE and PRAGMA foreign_keys = boolean;

invalid alter table option while modify foreign key

I want to modify the update option of one foreign key.
For this I executed this command:
alter table testusers.ORDERS
DROP CONSTRAINT ORDER_FK_2,
ADD CONSTRAINT ORDER_FK_2 FOREIGN KEY(FK_PRODUCER_ID) REFERENCES testuser.PRODUCER (producer_id)
ON UPDATE CASCADE ON DELETE CASCADE;
If I execute this, there is the following error:
SQL-Fehler: ORA-01735: Ungültige Option ALTER TABLE
01735. 00000 - "invalid ALTER TABLE option"
There is no comma separated list for the alter table according to documentation syntax diagram http://docs.oracle.com/cd/B28359_01/server.111/b28286/clauses002.htm#CJAEDFIB
create table orders(order_id number, fk_producer_id number, CONSTRAINT order_pk PRIMARY KEY (order_id));
create table producer(producer_id number, CONSTRAINT producer_pk PRIMARY KEY (producer_id));
alter table orders
ADD CONSTRAINT ORDER_FK_2 FOREIGN KEY( FK_PRODUCER_ID)
REFERENCES PRODUCER (producer_id) ;
alter table orders
DROP CONSTRAINT ORDER_FK_2;
alter table orders
ADD CONSTRAINT ORDER_FK_2 FOREIGN KEY( FK_PRODUCER_ID)
REFERENCES PRODUCER (producer_id) ;
Ahm, yes, and I could not find any ON UPDATE CASCADE syntax either. But I am sure you can work it out now. Otherwise drop a little comment or post a new question.

Create a foreign key in SQLite database browser

Sorry for novice question.
I have created my tables using SQLite database browser, but:
I do not know how can I specify my foreign keys using the application?
How can I create a relationship diagram between tables?
I know this question has been asked long ago but I found it. Its built right into GUI. You just need to drag and make those Name, Type tabs little bit small to make space for the Foreign Key tab. Place your mouse pointer at the end and drag the header.
My version of SQLite Browser is Version 3.7.0.
I couldn't find a way of defining foreign key constraints using the "Database Structure" tab. I'd strongly recommend defining table definitions and constraints using a script rather than building them using the graphical editor - it makes it much easier to create new databases and to track changes to the schema.
By way of an example, assume we have two tables: one defining file names and one specifying the method used for compression, we can add a foreign key constraint to the file_definition table when defining it.
CREATE TABLE [compression_state] (
[compression_state_id] INTEGER PRIMARY KEY NOT NULL,
[value] TEXT NOT NULL
);
CREATE TABLE [file_definition] (
[file_id] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
[compression_state_id] INTEGER NOT NULL,
[name] TEXT NOT NULL,
FOREIGN KEY(compression_state_id) REFERENCES compression_state(compression_state_id)
);
However, by default, SQLite will not enforce the constraint, therefore every time you connect to the database, you must issue the following command to enable constraint checking.
PRAGMA foreign_keys = ON;
Further details in the documentation.
If the tables already exist and you don't want to build a complete script then you're out of luck, SQLite doesn't support adding foreign keys once the table has been generated, see here: SQL Features That SQLite Does Not Implement
Go to edit table definition window
Click on Add field
Name it with Type : Integer
Scroll right and find Foreign Key column
Double click under Foreign Key column in new row
Select master table and its id field
Click OK
Click Write Changes
From the SQLite Documentation :
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER -- Must map to an artist.artistid!
);
and in the end :
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
In the DB Browser for SQLite Environment (v 3.8.0 - Sqlite v 3.9.2) when you add the DB fields for the track table along with
the PK ,AI and other columns you can find a Foreign Key Column.
In there , and for this example, you just add artist(artistid) in the trackartist row.
Then the foreign key constraint is created.
In DB Browser, in the Edit Table Definition window, you can double click the blank area of Foreign Key and a text box will activate. You can add your Foreign Key there.
it's really very easy , just do this
Go to edit table definition window
Right click on the table that you want to relate ( foreign table )
choose modify table
on Constraints tab select add constraints button and choose foreign key
you can relate tables here and then back to fields tab and do
Name it with Type : Integer
Scroll right and find Foreign Key column
Double click under Foreign Key column in new row
Select master table and its id field
Click OK
Click Write Changes
Triggers in SQLite3 enforces foreign key constraints. Link https://www.sqlite.org/cvstrac/wiki?p=ForeignKeyTriggers would help you out to solve your first question.
I am not sure whether this is entirely right but here's what I did:
I added the variable "UserID" in the fields tab an checked the box "primary key"
The I went to the constraints tab and added a foreign key Type constraint on the "UserID"
Then I went back to fields tab and double clicked on the foreign key field that opened and added the name of the table where that key is and the name of the variable

SQLITE: Unable to remove an unnamed primary key

I have a sqlite table that was originally created with:
PRIMARY KEY (`column`);
I now need to remove that primary key and create a new one. Creating a new one is easy, but removing the original seems to be the hard part. If I do
.indices tablename
I don't get the primary key. Some programs show the primary key as
Indexes: 1
[] PRIMARY
The index name is typically in the [].
Any ideas?
You can't.
PRAGMA INDEX_LIST('MyTable');
will give you a list of indices. This will include the automatically generated index for the primary key which will be called something like 'sqlite_autoindex_MyTable_1'.
But unfortunately you cannot drop this index...
sqlite> drop index sqlite_autoindex_MyTable_1;
SQL error: index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped
All you can do is re-create the table without the primary key.
I the database glossary; a primary-key is a type of index where the index order is typically results in the physical ordering of the raw database records. That said any database engine that allows the primary key to be changed is likely reordering the database... so most do not and the operation is up to the programmer to create a script to rename the table and create a new one. So if you want to change the PK there is no magic SQL.
select * from sqlite_master;
table|x|x|2|CREATE TABLE x (a text, b text, primary key (`a`))
index|sqlite_autoindex_x_1|x|3|
You'll see that the second row returned from my quick hack has the index name in the second column, and the table name in the third. Try seeing if that name is anything useful.

Resources