Row Not Being Deleted After ON DELETE Trigger Runs - sql

I am working in PostgreSQL 8.4 and have written a trigger function like so:
CREATE OR REPLACE FUNCTION otherschema.order_delete_log_procedure() RETURNS TRIGGER AS
$$
BEGIN
DELETE FROM otherschema.order_log AS thelog WHERE thelog.log_order_id=OLD.order_id;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER order_deletion_log_trigger BEFORE DELETE ON public.order FOR EACH ROW EXECUTE PROCEDURE
otherschema.order_delete_log_procedure();
My problem is, the trigger fires perfectly (the trigger is deleting the log row), however the row that is supposed to be deleted from the table that is firing the trigger is not getting deleted (the order isn't getting deleted).
If I try to delete the order row manually, it just says that no rows were affected and it gives no error. Any thoughts?
Thanks!

Returning NULL from a BEFORE DELETE trigger aborts the delete operation. You should return old instead, or make it an AFTER DELETE trigger.

Related

Postgres: Update table sorting on new record inserted or removed

I'm trying to sort table automatically by specified row each time a new record is added (or removed or updated).
For that, I've create a function
CREATE FUNCTION pid_cluster_function()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS $$
BEGIN
-- trigger logic
cluster verbose public.pid using pid_idx;
END;
$$
and add a trigger
CREATE trigger pid_cluster_trigger
after INSERT or update or DELETE on public.pid
FOR EACH row
execute procedure pid_cluster_function();
but with adding a record
INSERT INTO public.pid (pid,pid_name) VALUES ('111','new 111');
I've received such an error
SQL Error [55006]: ERROR: cannot CLUSTER "pid" because it is being used by active queries in this session
Where: SQL statement "cluster verbose public.pid using pid_idx"
PL/pgSQL function pid_cluster_function() line 5 at SQL statement
What is the reason for this error?
Or is it possible to achieve sorting by adding or modifying the records in some other way?
Ok, thank you, everyone, in the comments. I see that my idea is not clever =)

Understanding the BEFORE UPDATE trigger in SQL

In PostgreSQL, if I want to make changes on the UPDATE command, apparently I should trigger on BEFORE UPDATE. For example:
CREATE OR REPLACE FUNCTION trigger_update_fn() RETURNS trigger AS
$$ BEGIN
new.updated := current_timestamp;
new.created := old.created; -- override changes with original value
RETURN new;
END $$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_update
BEFORE UPDATE ON data
FOR EACH ROW
EXECUTE PROCEDURE trigger_update_fn();
In SQL Server there isn’t a BEFORE UPDATE trigger, and you make do with an AFTER UPDATE trigger. The point is that it seems to me that the trigger should work if it’s applied after the update in PostgreSQL, but it doesn’t, of course.
The question is why is the correct trigger a BEFORE UPDATE trigger, and what should I use the AFTER UPDATE trigger for?
The BEFORE trigger can modify the row about to be inserted into the table (NEW). The AFTER trigger runs after the table has been modified, so any changes to NEW have no effect on the persisted data.

Postgres: How to prevent anyone from updating a table?

I've been trying to stop any user from updating a table
I tried
REVOKE UPDATE ON TABLE NYAidCrimeMean FROM CURRENT_USER;
but when I try to update the table it still goes through, any pointers?
Well, I do not particular like triggers, but they have their uses. If you cannot find all the previous grants, you can get close here with one. See demo.
create or replace function no_no_no()
returns trigger
language plpgsql
as $$
begin
raise exception 'Cannot update table %s.', tg_table_name;
return null;
end;
$$;
create trigger No_no_no_NYAidCrimeMeanA
before update on NYAidCrimeMean
for each statement
execute function no_no_no();
If you really want to lock it down change before update to before insert or update or delete or truncate.
Of course a superuser can disable the trigger, then do whatever they want, but eventually get to where you must trust someone at some point.
The solution is as trivial as it is obvious: don't use superusers for anything but administative tasks.

Oracle Trigger Only Fires After I do a explicit Commit

I am new to triggers and just learning them. When I delete a row from the respective table I do not get a DBMS Output, but I know the row has been deleted. The only time I get a DBMS output for the trigger is when do a COMMIT or a RollBACK. Is this correct? Form what I have read the Trigger should automatically run when I delete a row but that doesn't seem to be the case for me. Additionally I ensured the trigger was enabled and set serveroutput was on.
create or replace Trigger tadr_Employee
After Delete ON employee
For Each Row
Begin
DBMS_OUTPUT.PUT_LINE('Tigger Fired After deleting anything from Lab10_Employees tadr');
End;
Delete FROM Employee
Where EmployeeID = 11111;

Solving the mutating table problem in Oracle SQL produces a deadlock

Hey, I'm trying to create a trigger in my Oracle database that changes all other records except the one that has just been changed and launched the trigger to 0. Because I am updating records in the same table as the one that launched the trigger I got the mutating table error. To solve this, I put the code as an anonymous transaction, however this causes a deadlock.
Trigger code:
CREATE OR REPLACE TRIGGER check_thumbnail AFTER INSERT OR UPDATE OF thumbnail ON photograph
FOR EACH ROW
BEGIN
IF :new.thumbnail = 1 THEN
check_thumbnail_set_others(:new.url);
END IF;
END;
Procedure code:
CREATE OR REPLACE PROCEDURE check_thumbnail_set_others(p_url IN VARCHAR2)
IS PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE photograph SET thumbnail = 0 WHERE url <> p_url;
COMMIT;
END;
I assume I'm causing a deadlock because the trigger is launching itself within itself. Any ideas?
Using an autonomous transaction for this sort of thing is almost certainly a mistake. What happens if the transaction that inserted the new thumbnail needs to rollback? You've already committed the change to the other rows in the table.
If you want the data to be transactionally consistent, you would need multiple triggers and some way of storing state. The simplest option would be to create a package with a collection of thumbnail.url%type then create three triggers on the table. A before statement trigger would clear out the collection. A row-level trigger would insert the :new.url value into the collection. An after statement trigger would then read the values from the collection and call the check_thumbnail_set_others procedure (which would not be an autonomous transaction).