I'm working on a script for school right now and I've encountered a weird error that I can't fix.
So I've got a playlist, tracks and a playlistInput table.
My task is to create a trigger that if I add/delete a track to my playlist, the amountOfTracks variable should be increased/decreased.
So now to the weird error:
I've made a function "playlistInputAdd" which already works when doing "select playlistInputAdd(1,1)".
The thing is that if I create my trigger, it says that this function doesn't exist. I've seen that someone asked the same question but he didn't add the parameters and I actually did.
The playlistInputAdd function:
CREATE FUNCTION playlistInputAdd(ID int, Amount int)
RETURNS VOID
AS $$
BEGIN
UPDATE playlist
SET amountOfTracks = amountOfTracks + Amount
WHERE playListID = ID;
END;
$$ LANGUAGE plpgsql;
The playlistInputAdd_trigger trigger:
CREATE TRIGGER playlistInputAdd_trigger
AFTER INSERT
ON playlistInput
FOR EACH ROW
EXECUTE PROCEDURE playlistInputAdd(playlistID, 1);
The playlistInputDelete_trigger trigger:
CREATE TRIGGER playlistInputDelete_trigger
AFTER INSERT
ON playlistInput
FOR EACH ROW
EXECUTE PROCEDURE playlistInputAdd(playlistID, 1);
The error message:
ERROR: function playlistinputadd() does not exist
Thank you, in advance!
Trigger functions must be defined with empty argument list and with RETURNS trigger. It is the argument list that causes the error you get.
You can pass arguments to the function in CREATE TRIGGER (even though the argument list has to be empty), but these have to be constants and can be accessed via TG_ARGV in the function body.
You don't need to pass the columns of the modified table as arguments: the row being inserted is available in the NEW variable in the trigger body.
See the documentation for more.
Related
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 =)
My goal is to create a schema, based on the uuid of a user.
I've therfor wrote a function that gets executed every time a user is created and confirmed.
As the documentation says PostgreSQL Documentation
i may have to write another function that creates a schema because of compatibility.
the 'create_user_schema()' function works in a new query but seems to not work if used in my trigger function. I've tried a lot with casting the uuid to a string but it still don't work.
Did i do something wrong, has this something to do with security and won't work in any case?
CREATE OR REPLACE FUNCTION user_setup() RETURNS trigger AS $user_setup$
DECLARE
s_name uuid := NEW.id;
BEGIN
-- cutout content that works so far
SELECT create_user_schema(CAST(s_name AS TEXT));
RETURN NULL;
END;
$user_setup$ LANGUAGE plpgsql;
CREATE TRIGGER user_setup AFTER INSERT OR UPDATE ON auth.users
FOR EACH ROW EXECUTE FUNCTION user_setup();
CREATE OR REPLACE FUNCTION create_user_schema(s_name text) RETURNS void AS $$
BEGIN
EXECUTE 'CREATE SCHEMA ' || quote_ident(s_name);
END;
$$ LANGUAGE plpgsql;
Well it wasn't really a bug and more some missing piece of information in "how postgres works".
It was necessary to add a 'Security Definer' keyword to the function to let the trigger have the correct privilges on execution.
I'm trying to activate a trigger when a new employee is added. the trigger should store the username of the person that has done the insert and the time it happened. Using Oracle database.
So far my code for the trigger is:
CREATE OR REPLACE TRIGGER insert_2
AFTER INSERT ON employees
for each row
DECLARE
vUser varchar(50);
begin
select user into vUser from dual;
insert into audit_cheker1 (date_create, inserted_by)
values (sysdate(), vUser);
END;
/
The trigger works but after I try to insert a new record it doesn't work and tells me error in the trigger.
The error message is telling you your trigger is invalid, that is it contains syntax errors and cannot be compiled. So you need to fix the compilation errors.
There are several ways to find errors. You can run a query:
select * from user_errors
where type = 'TRIGGER'
and name = 'INSERT_2'
/
You could use the SQL*Plus command show errors after the CREATE TRIGGER statement.
Or, as it seems you're using SQL Developer, you could open the trigger in the Object Navigator. You'll see the tab has several panes, one of which is labelled Errors. Open that pane to see what's wrong.
Here is one for free: although sysdate is technically a function it is a special one. It never takes any parameters and calling it with brackets is wrong. Remove these brackets: sysdate().
I have multiple tables in a PostgreSQL 9.6 database which changes I want to monitor and handle in an extern application.
Handling only data changes wasn't hard, but now I want to monitor structure changes of my database to be stored. This is what I have:
CREATE OR REPLACE FUNCTION log_structureChanged()
RETURNS event_trigger AS $$
BEGIN
UPDATE dbchanged SET changed=2 WHERE table_name = TG_ARGV[0];
RETURN NEW;
END;
$$ LANGUAGE PLPGSQL;
CREATE EVENT TRIGGER testData_struc
ON ddl_command_end
WHEN TAG IN ( 'CREATE TABLE', 'ALTER TABLE', 'DROP TABLE' )
EXECUTE PROCEDURE log_structureChanged();
When the EXECUTE PROCEDURE gets called, I want to parse the table that the changes have been made to. The official PostgreSQL documentation didn't really help me - I also may have not fully understood some parts.
So how do I parse the table on that the EVENT TRIGGER fired on? Is it stored inside a variable?
As described in the documentation, you can call the function pg_event_trigger_ddl_commands(), which will return one row per affected object.
You can either use the result column object_identity which contains a textual description of the affected object, or classid and objid, which contain the object ID of the catalog table that contains the object and the object ID of the affected object.
I need to make for my webApp a trigger to execute a stored procedure on Oracle. But i'm very new to Oracle and I'm still getting the hang of it. I can make a simple Trigger with a sequence to auto-increment a value from a table, but that's it.
Is there any good tutorials and examples available on this specific subject? I tried searching here, but i have only found a very generic question: How can i learn Stored Procedure and Trigger?. But i can be more specific: I need this trigger to run a stored procedure that generates a new code for my user, adding data to this code. The procedure is done, i just don't know how to use it in a trigger, pass the parameters, and how to insert/update values from the oracle trigger itself.
Help will be much appreciated.
Assuming your function to generate the code is named f_generate_code() and your table is named foobar and the column that should be populated is name code you'd do it like this:
create or replace trigger trg_update_code
before insert or update on foobar
for each row
begin
:new.code := f_generate_code();
end;
/