SQL Trigger prevent delete on single row - sql

I have a table where there is a row of data that I don't want anyone to deleted it. The Table name is ProjectInProcessData. I want to make sure the data with ID 6050 can not delete. How can I do that?

Create Trigger [dbo].[triggerPreventDeleteFormula]
ON [dbo].[AHSC_Project_InprocessData]
INSTEAD OF DELETE
AS
BEGIN
IF EXISTS(
SELECT *
FROM deleted d
where d.AHSC_Project_InprocessData_ID = '6610' or d.AHSC_Project_InprocessData_ID = '6666'
)
BEGIN
ROLLBACK;
RAISERROR('Can not delete this record: this record contains default formula',16,1);
END
ELSE
BEGIN
DELETE [AHSC_Project_InprocessData]
WHERE EXISTS (Select * from deleted d where d.AHSC_Project_InprocessData_ID = [AHSC_Project_InprocessData].AHSC_Project_InprocessData_ID)
END
END

use where condition in times of delete
delete from ProjectInProcessData where id!=6050

Related

I must not add row with 2 same values in columns

Can I enter a rule when creating a table so that I, as an author, can't add a review to a product I've already reviewed?
I've been thinking about triggers, but I don't know exactly how to set it. In the workbench I can check it via this code:
declare
pocet number := 0;
begin
SELECT COUNT(a."id_recenze")
INTO pocet
FROM "recenze" a
INNER JOIN (SELECT "id_komponenty", "id_autora"
FROM "recenze"
GROUP BY "id_komponenty", "id_autora"
HAVING COUNT(*) > 1) b
ON a."id_komponenty" = b."id_komponenty" AND a."id_autora" = b."id_autora";
if pocet > 2 then
DBMS_OUTPUT.put_line('Nesmite vytvaret recenzi na komponentu, u ktere jste uz recenzoval');
else
DBMS_OUTPUT.put_line('Vysledek je v poradku');
end if;
end;
But I don't want to be able to create these records.
Can someone help me, how i can do it?
I use APEX by Oracle.
EDIT: (24.4. 10:35)
In a nutshell, i don't want records, where id_autora & id_komponenty are more times. For example i don't want this:
id_recenze(PK) id_autora id_komponenty
1 2 3
2 2 3
After your explanation I see you could still use a unique index but you want to create it on id_komponenty and id_autora. That would throw an error if you tried to add a duplicate.
But I see from your code that you are trying to update with the most recent values if it's duplicated. In that case I would abandon the idea of the index and the trigger, and I would replace the INSERT statement (not shown) with Oracle's MERGE statement. This allows a simultaneous logic for insert and update, plus you get to define the criteria when you do either. It would look something like:
MERGE INTO recenze r
USING (Select <newid_komponenty> AS newk
,<newid_autora AS newa> from Dual) n
ON (r.id_komponenty=n.newk And r.id_autora=n.newa)
WHEN MATCHED THEN UPDATE SET {your update logic here}
WHEN NOT MATCHED THEN INSERT {your insert logic here}
Personally, I try to stay away from triggers when there are other solutions available. By altering your Insert statement to this Merge you get the same effect with one less DB object to keep track of and maintain.
I get it.
CREATE TRIGGER "nesmiPridat" BEFORE INSERT ON "recenze"
FOR EACH ROW BEGIN
DECLARE pocet INT(2);
DECLARE smazat INT(2);
SET pocet := (SELECT COUNT("id_recenze") FROM "recenze" WHERE (NEW."id_autora" = "id_autora") AND (NEW."id_komponenty" = "id_komponenty"));
SET smazat :=(SELECT "id_recenze" FROM "recenze" WHERE (NEW."id_autora" = "id_autora") AND (NEW."id_komponenty" = "id_komponenty"));
IF (pocet > 0) THEN
DELETE FROM "recenze" WHERE smazat."id_recenze" = NEW."id_recenze";
END IF;
END;

Delete after Insert trigger

I'm trying to create after insert trigger to delete a row from table whenever I insert the same row in the opposite table using the ID
But it doesn't work
Create Trigger [dbo].[MeritedDeceased] On [dbo].[Deceased]
After Insert
As
Begin
Delete From dbo.Merited Where dbo.Deceased.ID = dbo.Merited.ID
End
I think you mean to do something like this (maybe)...
CREATE TRIGGER [dbo].[MeritedDeceased] ON [dbo].[Deceased]
AFTER INSERT
AS
BEGIN
DELETE M
FROM [dbo].[MeritedDeceased] M
INNER JOIN Inserted I
ON I.ID = M.ID
;
END
;
Translation: Every time a row is inserted into dbo.Deceased, delete any rows with the same (inserted) ID from dbo.MeritedDeceased.
FYI, this TRIGGER won't just delete one row, but also a batch of rows that were inserted together. If that's what you want, then this should help.

T-SQL trigger after deleting

A need a trigger to run after a row is deleted from a table.
This trigger should delete rows from another table where a field on that table has a value matching the value of one of the columns of the deleted row from the other table.
If triggering the delete from a delete:
create trigger trg_mainTable
on dbo.mainTable
after delete
as
begin
delete
from dbo.relatedTable
where someColumn in
(
select someColumn
from deleted
)
end
go
If triggering the delete from an update:
create trigger trg_mainTable
on dbo.mainTable
after update
as
begin
if update(someColumn)
begin
delete
from dbo.relatedTable
where someColumn in
(
select someColumn
from deleted
)
end
end
go

How to prevent a row from being deleted based on the value of a column

Suppose we have a table called StudentAccount with columns SID (student Id) and AmountOwing.
We cannot delete the account from the system unless the student owes nothing on their account. (That is AmountOwing = $0.00).
For example the table could look like:
SID | Amount Owing
-------+--------------
32415 | $30.00
39872 | $0.00
35135 | $3200.00
In this case, we can delete row 2 only.
Is there a way to enforce this constraint on the table using valid MS SQL Server 2012 SQL syntax (so that an uneducated user won't accidentally delete a non-empty account)?
Try this:
CREATE TRIGGER trgD_StudentAccount_Delete
ON dbo.StudentAccount
INSTEAD OF DELETE
AS
BEGIN
IF EXISTS (
SELECT *
FROM deleted d
WHERE d.AmountOwing <> 0
)
BEGIN
ROLLBACK;
RAISERROR('Delete error: there are students with Amount <> 0', 16, 1);
END
ELSE
BEGIN
DELETE StudentAccount
WHERE EXISTS( SELECT * FROM deleted d WHERE d.[SID] = StudentAccount.[SID] )
END
END
Suggesting that you have AmountOwing as a number value (int, float, ...)
DELETE
FROM StudentAccount
WHERE AmountOwing > 0
Or work with a trigger (so that user should not delete any)
CREATE TRIGGER DML_ON_TABLEA
ON StudentAccount
AFTER INSERT,UPDATE
AS
BEGIN
SET NOCOUNT ON;
CASE
WHEN (AmountOwing = 0) THEN
-- DELETE STATEMENT
END
END
GO

Sql Server Triggers. How does the trigger checks for Update Command?

I have a trigger for auditing purchase and sales table. The trigger is on INSERT and DELETE. To check if its "Insert", the condition is
IF (SELECT COUNT(*) FROM INSERTED) > 0
BEGIN
END
How do I check if its an Update command inside the Trigger?
Arun
The "tables" that are in play in an update trigger are still called inserted and deleted, and the old values of the rows are in the deleted table, and the new values are in the inserted table.
You can use logic along these lines to detect whether you are in a insert, update or a delete:
CREATE TRIGGER MyTrigger
ON MyTable
AFTER INSERT,DELETE,UPDATE -- you need to add the "update" here,
-- in order to catch updates as well
AS
BEGIN
Declare #insertedCount int
Declare #deletedCount int
select #insertedCount = COUNT(*) from inserted
select #deletedCount = COUNT(*) from deleted
if (#insertedCount != 0) -- we have some new values
if (#deletedCount = 0) -- do we have old values?
print 'Inserting'
else
print 'Updating'
else
print 'Deleting'
END
An INSERT,DELETE trigger will not fire for updates.
.........................
CREATE an INSERT, UPDATE, DELETE all in one table
IF ##ROWCOUNT = 0
BEGIN
RETURN;
END;
IF EXISTS(SELECT * FROM inserted)
BEGIN
IF EXISTS(SELECT * FROM deleted)
BEGIN
-- for UPDATE
END
ELSE
BEGIN
-- for INSERT
END
END
ELSE
BEGIN
-- for DELETE
END;
Once you've updated your trigger (as Mitch says) to also apply to UPDATEs, you need to check for updates first:
IF EXISTS(select * from inserted) and EXISTS(select * from deleted)
BEGIN
--Update
END
Note that I've switch to EXISTS rather than COUNT(*). Exists more properly describes what we want to establish - that rows exist in the table. We don't care how many rows are in there.
I would like to thank "SWeko" for the clue.
Now, this what I did and the Trigger worked.
CREATE TRIGGER dbo.Sample
ON TableName
FOR INSERT, UPDATE, DELETE
AS
IF (SELECT COUNT(*) FROM INSERTED) > 0
BEGIN
IF (SELECT COUNT(*) FROM DELETED) > 0
BEGIN
-- UPDATE (TABLE).
END
ELSE
BEGIN
-- INSERT (TABLE).
END
END
ELSE
-- DELETE (TABLE).
BEGIN
END