How to ALTER a table on iSeries that has constraints? Getting "*FILE in use." error - sql

I have a table on a iSeries(IBM-i/AS400) which has some constraints. The table is created with SQL like so, with a handful of foreign keys linking from other tables to this table (actual SQL has been a bit obfuscated here):
CREATE TABLE ABCLIB.ABCDE (
DEIDN INTEGER NOT NULL WITH DEFAULT,
DETTL VARGRAPHIC (50) ALLOCATE(25),
DETYP CHAR (1) NOT NULL WITH DEFAULT);
ALTER TABLE ABCLIB.ABCDE ADD PRIMARY KEY (DEIDN);
ALTER TABLE ABCLIB.ABCFG ADD FOREIGN KEY (FGDEK)
REFERENCES ABCLIB.ABCDE (DEIDN)
ON DELETE RESTRICT ON UPDATE RESTRICT;
ALTER TABLE ABCLIB.ABCHI ADD FOREIGN KEY (HIDEK)
REFERENCES ABCLIB.ABCDE (DEIDN)
ON DELETE RESTRICT ON UPDATE RESTRICT;
Now, much later, I will need to alter that table to add a field:
ALTER TABLE ABCLIB.ABCDE ADD COLUMN DEICN VARGRAPHIC (100) ALLOCATE(50)
Which results in this message:
Row or object ABCDE in ABCLIB type *FILE in use.
I have checked and there are definitely no object locks on this table at this time. When I check the joblog, I see this:
Constraint cannot be removed from file Q_AT000000.
Constraint(s) not removed from file Q_AT000000.
File ABCDE in ABCLIB not changed.
Row or object ABCDE in ABCLIB type *FILE in use.
Now, I could of course remove and re-add the constraints in question, but I feel like this should not be necessary. The column I am adding has nothing to do with the constraints. I believe this probably is a result of the fact that in fact OS400 (i5/OS) is not really altering the existing table but instead is creating a new table and copying data in, and that is probably where the pain comes in.
But is there a way to possibly suspend the keys and then resume them after the alter?
(Answers that do not involve doing this with SQL or suggest creating the table differently in the first place are not helpful as they are not applicable here...)

The answer is: I missed the fact that there was a lock on one of the tables that had a foreign key pointing to that table. Or, put more bluntly: I am an idiot!

Does Enabling or disabling referential constraints help?

Related

drop all constraints in a postgresql table - drop cascade

I have 21 tables in my database. However, there are some issues with the table schema (as we are trying to improve our data model). I already referred this post but it is for SQL server.
Currently, just for validation purpose, I would like to upload data inside them.
However, some ill-defined constraints are causing trouble.
So, I would like to delete all constraints only (from all tables) like Foreign key, check , unique, PK, Index etc.
How can I do this?
Currently I tried the below
ALTER TABLE subject
DROP CONSTRAINT subject_details_pk CASCADE;
ALTER TABLE subject
DROP CONSTRAINT subject_foreign_fk CASCADE;
As you can see, I have to write line by line across different tables (and manually find out which table is parent and which table is child etc).
So, is there any other way to drop all constraints in a table? Like Drop cascade ?
Can help me with this?

How to add a foreign key for a table that is already created?

I have added a table to a database called settings. This table has a column called id (integer) which is the pirmary key. I have also added a column called settingsID to a table called sessions. What I want to do is add a foreign key to settingsID which references the primary key.
I don't want to create a new table as it is already created. All I want to do is to references the id from the settings table in settingsID which is in sessions table.
ALTER TABLE Sessions ADD FOREIGN KEY (_SettingsID) REFERENCES settings (id)
Here is my error:
near "FOREIGN": syntax error
Can someone tell me the right way to approach this?
Short answer: you can't.
This is documented as part of the SQL Features That SQLite Does Not Implement:
Only the RENAME TABLE, ADD COLUMN, and RENAME COLUMN variants of the ALTER TABLE command are supported. Other kinds of ALTER TABLE operations such as DROP COLUMN, ALTER COLUMN, ADD CONSTRAINT, and so forth are omitted.
Bold emphasis is mine.
So basically you would need to create the constraint at the time when the table is created. For your use case, one solution would be to:
create a new table (with the foreign key constraint)
copy the data from the old table
drop the old table (or better yet, rename it, so you have a backup)
rename the new table

Adding foreign key fails unless data is first removed and reinserted after

I have an odd issue with foreign keys. I am trying to perform the following query:
ALTER TABLE [GroupMember] FOREIGN KEY ([Group]) REFERENCES [Group]([GUID])
Which gives me the following error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__GroupMember__Group__0D25C822". The conflict occurred in database "x", table "dbo.Group", column 'GUID'.
I then verified the existing things, which I have confirmed are all ok:
Referenced table (dbo.Group) has a defined PRIMARY KEY on [GUID] column
Referencing table (dbo.GroupMember) has no [Group]-values which do not exist in [GUID]-column of dbo.Group-table
No similarly referencing foreign keys exist already
From here on, I experimented. Taking some rows in and out, wiping the table, truncating the table. What I can conclude so far:
If I wipe the referencing table using DELETE FROM [GroupMember]; then try to apply the FK constraint, I receive the same error message
If I truncate the referencing table using TRUNCATE TABLE [GroupMember];, I can apply the FK constraint without errors. Additionally, I am able to reinsert the exact same data after applying the FK constraint, without problems.
From this I can conclude that the data itself is not the problem. Can anyone make sense of this? Why am I able to apply the constraint after truncating the table, but not after deleting all records?
If you are using Microsoft SSMS check whether unchecking "Prevent saving changes that require table re-creation" solves the problem. You'll find this in Options > Designers > Table and Database Designers.
I have had similar issues that have been resolved by this. Let me know if it works or not.
Good luck.

Index should be dropped but is preventing new primary key from being added

I have a strange situation that I don't understand. I am running a block of SQL in a merge module to update a oracle schema. I am trying to change the primary key of several tables so I am performing the following steps:
Drop FK constraints,
Drop PK,
Drop PK Index (if the index persists after the PK is dropped),
Add new PK,
Add FK's
Here's my problem. All is well until we get to the part where indexes are dropped. The primary is dropped and (to the best of my knowledge) any index that Oracle created based on that key will drop instantly as well. I was having issues with the index persisting so I added the DROP INDEX script to be certain it is removed, however, this is what happens:
Alter Table TABLE1 Drop Constraint TABLE1_PK
The command ran successfully
DROP INDEX TABLE1_PK
ORA-01418: specified index does not exist (This is exactly what I expected)
ALTER TABLE TABLE1 ADD (CONSTRAINT TABLE1_PK PRIMARY KEY (TABLE_KEY) ENABLE VALIDATE)
ORA-00955: name is already used by an existing object (The object being, in each case, the old index)
This of course prevents any of the FK's from linking because they are now based on the new key. When I run this in TOAD, the SQL works, but I can't figure out why it doesn't through the merge module. Can anyone help?

Foreign Keys left after table deletion?

So here's an interesting one for you... I am working on copying one entire database (db1) and structure over from one database to another (db2), and before doing so I decided to try and drop all tables from the db2. I did the usual sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAING ALL' and then sp_msforeachtable 'DROP TABLE ?' and much to my dismay, it deleted all save for maybe 6 tables. These tables seemed to still have foreign key references to them. I did a search and found this SQL DROP TABLE foreign key constraint which showed me how to find and then try to delete those foreign key references.
This is the interesting part: upon attempting to delete them using that information, I have been told that ssms cannot find the object because it does not exist or I do not have permission. The foreign key reference is coming from a table that I have previously deleted.
How is that possible? And how on earth do I progress from here?
I don't know what you mean by them in "upon attempting to delete them". If you were trying to delete the foreign key from the system tables, that would definitely be a mistake.
My guess is you can just drop those last 6 tables now.
Suppose we have two tables A and B
create table A (a int)
create table B(b int, foreign key (b) references (A.a))
and we try to drop the tables. drop table A will fail, because B references it with a declared foreign key. But we can freely drop table B, because A doesn't care if it's no longer being referenced.
So after the first pass, one DROP failed and one succeeded, leaving one table, now with no FK references. Try again and, voila!, drop table A now works.