How to prevent delete query in SQL - sql

I have created a database through Entity Framework Code First Approach and My application is ready and running live . The problem is that I did not turned "False" on Cascade Delete at the time of creating database.
Now if I delete any record from one table that is referenced with another table through foreign so all the record containing foreign key of deleted row is deleted from another table .
Practically demonstration :
Let say I have a Table called Passenger:
ID Name CategoryID
1 ABC 1
CategoryID here is a foreign key
Here is the category Table
ID Name
1 Gold
Let say I run my query on category table
delete from Category where ID = 1
Now all the record from my Passenger Table is deleted . I want to restrict it. Is it Possible through SQL now ?

I suppose
This is what you are looking for :
alter TRIGGER customers_del_prevent
ON dbo.customers
INSTEAD OF DELETE
AS
BEGIN
insert into dbo.log
values ('DELETE')
RAISERROR ('Deletions not allowed from this table (source = instead of)', 16, 1)
END
Hope this helps you. :)

Related

Create a loop function which passes in the foreign key

I am working on an assignment where I have to create a database using SQL Server 2019. I am wondering how to create a function which uses the existing PK of one table and puts it into the FK of the linked table. I can't upload a picture of it. But here is a description of my two tables:
Table Item:
Columns: itemID(PK), itemPackID(FK), description......
Table ItemPack:
Columns: ItemPackID(PK) ItemID(FK), quantity...
In the Item table, itemPackID as a foreign key is holding NULL and I want to replace the NULL with the PK value of the ItemPack table.
I'm considering that itemID(PK) is not null in ItemPack table. Please check the bellow code, hope this will help you.
SQL query:
UPDATE Item SET [itemPackID(FK)] = (SELECT [ItemPackID(PK)] FROM ItemPack WHERE [ItemID(FK)]=[itemID(PK)]) WHERE [itemPackID(FK)] IS NULL
Thank you

How to update a value in 1 table with the newly created PK of another table

I'm currently developing a project where I need to create a record in one table and leave the last column as NULL and update this later with the PK of another table (to establish a link).
Table 1 is a table for courses and table 2 is a table for the feedback form for each course.
The user first makes the course which is inserted in to table 1, THEN they make the feedback form which is inserted in to table 2.
Now I wanted to use a PK+FK relation here but, I can't set the FK of table 1 as the record hasn't yet been created in table 2.
For example, table 1 has the columns:
id(int)(PK), column1(int), column2(int), linkColumn(int)
Table 2 has the columns:
id(int)(PK), column1(int),...
I need to be able to make a record in table 1 and set linkColumn to NULL initially.
Then I need to create a record in table 2 and update linkColumn in table 1 with the Primary key of the newly created record in table 2.
How would I go about this?
Thanks!
Edit: I'm using PHP as the SQL handler
Use Triggers on insert for each row on Table2.
What Database are you using?
EDIT:
CREATE TRIGGER T_TABLE2_AI
AFTER INSERT
ON TABLE2 FOR EACH ROW
BEGIN
update Table1 set linkColumn = :new.ID where column1 = :new.column1;
END;

Converting Pseudocode to SQL Script

So I have two tables:
Bookmarks has a few columns [id, etc.]
Person_Bookmark has 2 columns [personId, bookmarkId]
Bookmarks represents links to other websites. All valid bookmarks have an id. The Person_Bookmark table has a bunch of personIds and their bookmarks, shown as bookmarkId.
Here's my pseudocode:
> let x = integer list of all bookmarkId's from Person_Bookmark
>
> for each x {
> if ('select * from 'Bookmarks' where 'id' = x returns 0 rows) {
> delete from 'person_bookmark' where 'bookmarkId' = x
> }
> }
Please advise me how to convert to a Postgres [edit] SQL script.
#Jan mentioned foreign keys already, but his advice is incomplete.
Seems like you want to delete all associations to a bookmark that does not exist (any more).
Define a foreign key constraint in the form of:
ALTER TABLE person_bookmarks
ADD CONSTRAINT pb_fk FOREIGN KEY (bookmarkid) REFERENCES bookmarks (id)
ON UPDATE CASCADE
ON DELETE CASCADE;
This only allows values in person_bookmarks.bookmarkid that exist in bookmarks.id.
ON UPDATE CASCADE changes corresponding values in person_bookmarks.bookmarkid when you change an entry in bookmarks.id
ON DELETE CASCADE deletes corresponding rows in person_bookmarks.bookmarkid when you change an entry in bookmarks.id.
Other options are available, read the manual.
The ON DELETE CASCADE clause does automatically, what you are trying to fix manually. Before you can add the fk constraint you'll have to fix it manually once:
DELETE FROM person_bookmarks pb
WHERE NOT EXISTS (SELECT 1 FROM bookmarks b WHERE b.id = pb.bookmarkid);
-- OR NOT EXISTS (SELECT 1 FROM persons p WHERE p.id = pb.personid);
Deletes all rows with non-existing bookmarkid. Uncomment the last line to get rid of dead persons, too.
This works in SQL Server - not sure about MySQL...
delete pb
from
person_bookmark pb
where not exists (select 1 from booksmarks b where b.id = pb.bookmarkid)
Another version of #Derek's reply:
DELETE FROM person_bookmark
WHERE bookmarkid NOT IN (SELECT id FROM bookmarks)
The need to do this implies that you have no foreign key indexes between your tables. I strongly advise you to do so. The drawback (or feature) lies in that when you for example delete a person (I'm guessing this table exists from your example), you have to delete all associated data first, otherwise the server will throw an error.
Something like this:
DELETE FROM person_Bookmark WHERE personid = #personid
DELETE FROM person_SomeOtherTable WHERE personid = #personid
DELETE FROM person WHERE id = #personid
The advantage though is that you'll have no orphan rows in your database, and you can't enter erroneous data by mistake (store a bookmark for a person that doesn't exist).

Duplicate key exception when updating (not inserting) a field in a DB table

I created a trigger for a table (Person) so that each time a new Person entry is created its ID is inserted in another table (Person_ID). Person_ID table has only 2 rows: ID (primary key, int and Identity) and Person_ID (GUID whose values is passed with the trigger).
This schema cannot be changed due to other dependencies with our business logic.
Now I need to update a field of Person table with the Person_ID.ID (the identity automatically generated once that person has been created). To do that I created a trigger for Person_ID so that once a new entry is created, the generated ID will updated the target field in Person table:
UPDATE Person
SET target_Person = (SELECT JPerson_ID.ID FROM inserted)
WHERE Person.ID IN (SELECT JPerson_ID.PersonID FROM inserted)
When I create a new Person I get the following exception:
Violation of PRIMARY KEY constraint 'TBL_PERSON_A_PK'.
Cannot insert duplicate key in object 'dbo.TBL_PERSON_A.
There is an update trigger associated to table Person that comes from a legacy component and I cannot edit or see it (it is encrypted). It seems the reason of the exception above.
Why do I get this exception even if I simply make an UPDATE and not an insert?
To solve this I disable such a trigger before executing the update and then enabling it again and it works like a charm:
EXECUTE sp_executesql N'DISABLE TRIGGER dbo.TBL_PERSON_TRU1 ON PERSON'
...
EXECUTE sp_executesql N'ENABLE TRIGGER dbo.TBL_PERSON_TRU1 ON PERSON'
However how can I be sure that this will not bring to logic errors?
Thanks.
I don't know if this causes your problem, but have you kept in mind that your (SELECT JPerson_ID.ID FROM inserted) could return more than one row?
So you insert trigger must be changed to somewhat like:
CREATE TRIGGER [dbo].[trgJPerson_ID] ON [dbo].[TBL_PERSON_A]
FOR INSERT
AS
INSERT INTO dbo.JPerson_ID(ID )
SELECT ID FROM inserted
and accordingly the delete-trigger(if you have one)
CREATE TRIGGER [dbo].[trgJPerson_ID] ON [dbo].[TBL_PERSON_A]
FOR DELETE
AS
DELETE FROM dbo.JPerson_ID
WHERE ID IN(SELECT ID FROM DELETED)
Unless I have misunderstood, you seem to have answered your own question; it appears that the trigger you can't see the definition of is doing something to prevent the update statement from completing.
Without knowing what that trigger does I can't see how we can help you.
As a side note, I don't understand why you are updating the Person table with the ID from the Person_ID table. It seems a bit pointless really as you can just join on to the Person_ID to retrieve the ID
Select p.ID, -- The Person GUID
p.Name,
pi.ID -- The Person_ID ID
From dbo.Person p
Join dbo.Person_ID pi on p.ID = pi.PersonID

SQL Server : Changing an ID to an already existing one (merge) HOW TO?

I have two records that are the same in a table (entered by mistake). Both IDs are used as foreign key in other tables. I want to update the foreign keys to one "orignal" element and delete the other one. The problem is that it's possible that the UPDATE of the foreign key will generate a constraint exception (if the foreign key with the original element already exists).
So I would do something like :
UPDATE foreignTable SET id=1 WHERE id=2
DELETE FROM firstTable WHERE id=2
The problem is with the UPDATE, I would like to do the UPDATE if the row doesn't already exists, if yes just DELETE the row. How do you do that?
UPDATE ft
SET id = 1
FROM foreignTable ft
LEFT JOIN foreignTable ft2
ON ft.PrimaryKey = ft2.PrimaryKey
AND ft2.id = 1
WHERE ft.id = 2
AND ft2.PrimaryKey IS NULL
DELETE FROM foreignTable
WHERE id = 2
If you are using SQL Server 2008, have a look at the MERGE statement.
It allows you to insert the missing rows, update the existing one and delete those who have to be deleted.
http://technet.microsoft.com/en-us/library/bb510625.aspx
If you use an older version, you will have to copy your data to a temporary table, delete the data from the existing one and reinsert from the temp table.
Be sure to use a transaction and make a backup of your table to avoid data loss.