I needed to delete a column from a table that other tables had a foreign constraint on. I guess ALTER TABLE doesn't let you remove columns, so I had to create a new table without the column and copy the data over and rename them appropriately. Though now it won't let me delete the old table with the extra column because of foreign table constraints still I guess pointing to the old table instead of the new one... even though the new one now has the correct name. What is the recommended practice for making the foreign keys point to the right table now that I did the switch?
I don't think that you can. You might have to recreate all the other tables with the updated foreign key, because you cannot change foreign key constraint conditions or at least as far as I know.
Related
I am currently working on a database structure in SQLite Studio (not sure whether that's in itself important, but might as well mention), and error messages are making me wonder whether I'm just going at it the wrong way or there's some subtlety I'm missing.
Assume two tables, people-basics (person-ID, person-NAME, person-GENDER) and people-stats (person-ID, person-NAME, person-SIZE). What I'm looking into achieving is "Every record in people-basics corresponds to a single record in people-stats.", ideally with the added property that person-ID and person-NAME in people-stats reflect the associated person-ID and person-NAME in people-basics.
I've been assuming up to now that one would achieve this with Foreign Keys, but I've also been unable to get this to work.
When I add a person in people-basics, it works fine, but then when I go over to people-stats no corresponding record exists and if I try to create one and fill the Foreign Key column with corresponding data, I get this message: "Cannot edit this cell. Details: Error while executing SQL query on database 'People': no such column: people-basics.person" (I think the message is truncated).
The DDL I currently have for my tables (auto-generated by SQLite Studio based on my GUI operations):
CREATE TABLE [people-basics] (
[person-ID] INTEGER PRIMARY KEY AUTOINCREMENT
UNIQUE
NOT NULL,
[person-NAME] TEXT UNIQUE
NOT NULL,
[person-GENDER] TEXT
);
CREATE TABLE [people-stats] (
[person-NAME] TEXT REFERENCES [people-basics] ([person-NAME]),
[person-SIZE] NUMERIC
);
(I've removed the person-ID column from people-stats for now as it seemed like I should only have one foreign key at a time, not sure whether that's true.)
Alright, that was a little silly.
The entire problem was solved by removing hyphens from table names and column names. (So: charBasics instead of char-basics, etc.)
Ah well.
This is really annoying, I've encountered this problem plenty of times when importing a database:
https://i.gyazo.com/8051625ceaa6f2e00212a134a96a485e.png
Because it has no unique column, I can't delete rows. Because I can't delete rows, I can't assign a unique column because I can't delete the rows with duplicate entries for that column (those rows with ID = 0).
I can't remember how I fixed this before. I have no idea how this problem even happens, I thought the wp_options table would have a unique key on the ID column by default.
Ah, sorry the solution was really simple. PHPMyAdmin just prevents you from deleting rows through the GUI, but the SQL query to delete the rows still works. I deleted those duplicate rows by going into the SQL tab and running DELETE FROM wp_options WHERE option_id = '0';
I've also encountered this problem, and thought the same thing (NOTE: It's NOT just the wp_options table - you're going to have issues on other tables as well!)
The issue is the way the export / import is processed.
There's a subtle "autoincrement" checkbox somewhere in the phpMyAdmin interface for the export under the "object creation" options:
NOTE: Once you've exported / imported, and find yourself dealing with this, the simplest way that I've come up with to solve the issue is:
Create a new column titled 'new_ID', make it AUTO_INCREMENT.
Then,
a. either run a query to update the existing ID column to the new_ID value, OR
b. Delete the existing ID column, and rename 'new_ID' to the correct name, and add a PRIMARY KEY index.
I figured out what caused the problem. When importing the SQL file, there was an error when importing one of the keys for one of the tables. As a result, it skipped the importing of every key after that, and the option_id unique key was one of the keys it skipped. So yeah you were right, the problem happened with a lot of other tables too. The solution was to import the rest of the keys and indexes and stuff from the .sql file.
What I mean is this:
--
-- Indexes for table wp_links
ALTER TABLE wp_links
ADD PRIMARY KEY (link_id), ADD KEY link_visible (link_visible);
--
-- Indexes for table wp_options
ALTER TABLE wp_options
ADD PRIMARY KEY (option_id), ADD UNIQUE KEY option_name (option_name), ADD KEY wpe_autoload_options_index (autoload);
I forgot to delete the wp_links table before importing the new database tables, so it couldn't create the link_id primary key since it already existed. As a result, every key that appeared in the file after that one got skipped.
I have a Dataset that has 3 TablesAdapters linked together (both the relationships and foreign-keys came over from the DB design). I'm trying now to to bind the TableAdapter with the foreign keys on it, I get the following:
"Failed to enable constraints. One or more rows contain values
violating non-null, unique, or foreign-key constraints."
so after a little digging, I found that it doesn't like that I have Identical foreign keys on the TableAdapter (even though the DB contraints are OK with this).
How to I get my DataSet (or the TableAdpapter) to only look at the primary key of the table as a contraint?
Ok, so 5 seconds after I post this I find the answer (isn't that how it always works?)
The problem was that I added a table adapter that queried from my multiple tables, not just a single table. This tableAdapter looks like it just "decided" what columns to use for unique Contraints.
To fix the issue, I had to go into the Dataset designer and search for "UniqueConstraint" until I found the one that was using two foreign key columns of the restraint instead of the one primary key.
I have a SQLite table that looks like this:
CREATE TABLE Cards (id INTEGER PRIMARY KEY, name TEXT)
So each time I create a new row, SQLite is going to automatically assign it a unique ID.
However, if I delete a row and then create a new row, the new row is going to have the ID of the previously deleted row.
How can I make sure it doesn't happen? Is it possible to somehow force SQLite to always give really unique IDs, that are even different from previously deleted rows?
I can do it in code but I'd rather let SQLite do it if it's possible. Any idea?
Look at autoincrement (INTEGER PRIMARY KEY AUTOINCREMENT). It will guarantee this and if the request can't be honored it will fail with SQLITE_FULL.
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.