ON DELETE SET NULL in postgres - entity-framework

HI I'm new to postgresql environment so been lost for a while. I want to keep my data when parent entity is deleted. I want to know how to make 'ON DELETE SET NULL' for postgresql database. Please give me a clue.

ON DELETE SET NULL is a standard foreign key constraint option.
CREATE TABLE some_child (
parent_id integer references parent(id) on delete set null
);
or:
ALTER TABLE some_child
ADD CONSTRAINT parent_id_fk
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE SET NULL;
See the documentation.
In future posts make sure you include your PostgreSQL version and explain what you've already tried.

Related

postgres not setting foreign key to null when truncating

I'm trying to truncate a set of tables, but it keeps complaining about a foreign key.
but that foreign key is set to on delete Set null
to reproduce:
create table test_players (id SERIAL PRIMARY KEY, name VARCHAR(255));
create table test_items (id SERIAL PRIMARY KEY, name VARCHAR(255), player_id INTEGER FOREIGN KEY (player_id) REFERENCES test_players(id) ON DELETE SET NULL);
now if you truncate the test_players it will complain:
ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "test_items" references "test_players".
HINT: Truncate table "test_items" at the same time, or use TRUNCATE ... CASCADE.
SQL state: 0A000
what must I do to make me be able to delete test_players without deleting the test_items?
You cannot do what you are attempting. You will have to do this in 3 steps.
Update test_items and for each player_id. Well technically you don't need this, but if you don't give yourself data integrity issues.
Drop the test_items to test_players FK.
Then truncate test_players
The reason is that truncate basically just zaps the table, it does NOT process individual rows. Therefore it would not process the FK set null, it throws the error you got instead. In fact even if the child table is empty, or for that matter even if the parent is empty. See fiddle here. The fiddle also contains a function to do it, and a test for it.
The of course you could just Delete from test_players and let the triggers take care of updating test_items. Takes longer, esp if larger table, but you keep your FK. Of course there's
Recreate your FK.

Make a previously existing foreign key column have a unique constraint in postgres

I need to create a migration for an already existing table to make it's foreign key have a UNIQUE constraint. How do I do this?
From the examples I found in the documentation, it is mostly done when the table is created. The issue is I need to add this onto a column that already exists and is already set as a foreign key. This is what the table looks like at it's creation:
CREATE TABLE IF NOT EXISTS "myTable" (
"_id" SERIAL NOT NULL,
"myForeignKeyId" INTEGER NOT NULL,
"name" VARCHAR(255) NOT NULL,
CONSTRAINT "pk_myTable" PRIMARY KEY ("_id"),
CONSTRAINT "fk_myTable_myForeignKeyId" FOREIGN KEY ("myForeignKeyId") REFERENCES "myOtherTable" ("_id")
);
What I want to do is on a migration make myForeignKeyId unique. How do I do that?
I have tried to following:
CREATE UNIQUE INDEX CONCURRENTLY "myTable_myForeignKeyId"
ON province ("myForeignKeyId");
ALTER TABLE IF EXISTS "myTable"
ADD CONSTRAINT "myForeignKeyId"
UNIQUE USING INDEX "myTable_myForeignKeyId";
First off, when I try this in a migration I get the error:
CREATE INDEX CONCURRENTLY cannot run inside a transaction block
So that part cannot be done, but even just doing it through SQL, the second part doesn't work either as it claims myForeignKeyId already exists. Even if I add an ALTER COLUMN myForeignKeyId it just says there is an error on that line.
This seems like it should be a simple enough operation, how can I do this?
After digging some more found quite a simple way to do this, was clearly originally off target.
To add a unique constraint to a column:
ALTER TABLE "myTable"
ADD CONSTRAINT "myUniqueKeyNameOfChoice" UNIQUE ("myColumn");
To remove it:
ALTER TABLE "myTable"
DROP CONSTRAINT "myUniqueKeyNameOfChoice";

How to use cascade update on PK in postgresql

ALTER EMPLOYEE
DROP CONSTRAINT MGR_SSN
Change all SSN ON UPDATE CASCADE
When an employee’s SSN is updated
- then propagate that change to all pertinent FKs
Link to DB: https://www.db-fiddle.com/f/wCwvN6pFq2cXvfuE57QTum/0#&togetherjs=8aityz4DAt
If you need to update a primary key, your DB design is not good.
That being said, it is possible to add a foreign key to a table with the constraint you have given. See below (I have added a ON DELETE SET NULL).
I repeat: I recommend you review your DB design.
ALTER TABLE Employee
ADD FOREIGN KEY (Mgr_SSN) REFERENCES Employee(SSN) ON DELETE SET NULL ON UPDATE CASCADE

Errors creating constraint trigger

Let me start by saying that I’m a Linux/Unix admin. That being said my manager has tasked me with moving older PostgreSQL databases to a RedHat server running 8.4.20. I was successful moving a 7.2.1 db but I’m running into issues moving a 7.4.20 db.
I use pg_dump –c filename and psql < filename. For the problematic db everything runs until I get to a CREATE CONSTRAINT TRIGGER statement. If I run it as it is in the file I get :
NOTICE: ignoring incomplete trigger group for constraint "" FOREIGN KEY data(ups) REFERENCES upsinfo(ups)
DETAIL: Found referenced table's DELETE trigger.
CREATE TRIGGER
If I run set schema 'pg_catalog'; I get:
ERROR: relation "upsinfo" does not exist
The tables (I think) involved are:
CREATE TABLE upsinfo (
ups text NOT NULL,
ipaddr inet,
rcomm text,
wcomm text,
reachable boolean,
managed boolean,
comments text,
region text
);
CREATE TABLE data (
date timestamp with time zone,
ups text,
mib text,
value text
);
The trigger problem trigger statement:
CREATE CONSTRAINT TRIGGER "<unnamed>"
AFTER DELETE ON upsinfo
FROM data
NOT DEFERRABLE INITIALLY IMMEDIATE
FOR EACH ROW
EXECUTE PROCEDURE "RI_FKey_cascade_del"('<unnamed>', 'data', 'upsinfo', 'UNSPECIFIED', 'ups', 'ups');
I know that the RI_FKey_cascade_del function is defined differently in the different versions of pg_catalog. Note that search_path is set to ‘public, pg_catalog’ so I’m also confused why I have to set the schema.
Again I’m not a real PostgreSQL DBA so try to be kind.
Oof, those are really old postgres versions, including the version you're upgrading to (8.4 was released in 2009, and support ended in 2014).
The short answer is that, as long as upsinfo and data are being created and populated, you're probably fine, and good to go. But one of your foreign key relationships is broken.
The long answer, well, let me see if I can explain what is going on (or, at least, what I think is going on).
I'm guessing that the original table definition of data included something like FOREIGN KEY (ups) REFERENCES upsinfo (ups) ON DELETE CASCADE. That causes postgres to automatically make some trigger constraints: 1- every time there's a new row for data, make sure that its ups column matches an existing row in upsinfo, and 2- every time you delete a row from upsinfo, delete the corresponding rows in data, based on the matching ups value.
That (not very informative) error message can come up when the foreign key relationship doesn't work. In order for a foreign key to make sense, the referenced value needs to be unique -- there should be only one row in upsinfo for each distinct value of ups. In order for postgres to know that, there needs to be a unique index or primary key on upsinfo.ups.
In this case, one of a couple things could be breaking it:
There's no primary key or unique index on upsinfo.ups (postgres should not have allowed a foreign key, but may have in very old versions)
There used to be a unique index, but it hadn't properly enforced uniqueness, so it didn't get successfully imported (a bug, again likely from a very old version)
In either case, if that foreign key relationship is important, you can try to fix it once the import is complete. Start by trying to make a unique index on upsinfo.ups, and see if you have problems. If you do, resolve the duplicate entries, and try again till it works. Then issue something like:
ALTER TABLE data
ADD FOREIGN KEY (ups) REFERENCES upsinfo (ups) ON DELETE CASCADE;
Of course, if things are working, it's possible you don't need to fix the foreign key, in which case you're probably able to ignore those errors and just move forward.
Hope that helps, and good luck!
This seems to be a part of ON DELETE CONSTRAINT. If I were you I would delete all such statements and replace them with a proper constraint definition on the target table.
Table definition should then look like this:
CREATE TABLE bookings (
boo_id serial NOT NULL,
boo_hotelid character varying NOT NULL,
boo_roomid integer NOT NULL,
CONSTRAINT pk_bookings
PRIMARY KEY (boo_id),
CONSTRAINT fk_bookings_boo_roomid
FOREIGN KEY (boo_roomid)
REFERENCES rooms (roo_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
) WITHOUT OIDS;
And this part is what will internally create the trigger:
CONSTRAINT fk_bookings_boo_roomid
FOREIGN KEY (boo_roomid)
REFERENCES rooms (roo_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
But, to be honest, I do not have an understanding for an upgrade to an unsupported version. You know the Postgres is version 9.5 now, right?

T-SQL Unique constraint locked the SQL server

HI !
This is my table:
CREATE TABLE [ORG].[MyTable](
..
[my_column2] UNIQUEIDENTIFIER NOT NULL CONSTRAINT FK_C1 REFERENCES ORG.MyTable2 (my_column2),
[my_column3] INT NOT NULL CONSTRAINT FK_C2 REFERENCES ORG.MyTable3 (my_column3)
..
)
I've written this constraint to assure that combination my_column2 and my_column3 is always unique.
ALTER TABLE [ORG].[MyTable] ADD
CONSTRAINT UQ_MyConstraint UNIQUE NONCLUSTERED
(
my_column2,
my_column3
)
But then suddenly.. The DB stopped responding.. there is a lock or something..
Do you have any idea why?
What is bad with the constraint?
What I've already checked is that I have some locked objects when I select * from master.dbo.syslockinfo (joined with sysprocesses). After 10 minutes of inactivity.. this list is empty again and I can access all the objects in database. Weird..
It has to lock the table while checking the data to see if it violates the constraint or not, otherwise some bad data might get inserted while it was doing this
Some operations like rebuilding an index (Of course not using the ONLINE in Enterprise Edition) also will make the table inaccessible while it does this