I want to call a certain procedure that logs everytime a database user is created or deleted in the db ( sql Anywhere 16).
For this i have written a Function that should be called via a trigger when a row is inserted or deleted from table SYS.SYSUSER.
However, I am not able to create a trigger on this table.
Am i allowed to create trigger on this or is there someother way to get notified whenever a user is created or deleted for db?
New to sybase please help.
heres is my create trigger code
CREATE TRIGGER myTrigger AFTER INSERT ON sys.sysuser
REFERENCING NEW AS newRecord
FOR EACH ROW
BEGIN
--
END;
You cannot create a trigger on a system table. You can create a handler for "system events", which are described in the online SQL Anywhere documentation. Unfortunately, creation or deletion of users is not a system event that can be handled. I don't believe there's a way short of polling that you can do what you want to do.
Full disclosure: I work for SAP in SQL Anywhere engineering.
Related
This question already has an answer here:
Drop trigger/function at end of session in PostgreSQL?
(1 answer)
Closed last month.
I'm trying to create a system in Postgres where each client can create its own subscriptions via listen + notify + triggers. I.e. the client will listen to a channel, and then create a trigger which runs notify on that channel when its conditions have been met. The issue is that I want Postgres to clean up properly in case of improper client termination (e.g. the remote client process dies). To be more specific, I want that trigger which is calling the notify to be removed as there is no longer a listener anyways. How can I accomplish this?
I've thought about having a table to map triggers to client ids and then using that to remove triggers where the client is gone, but it seems like a not so great solution.
I found an answer to this in another question: Drop trigger/function at end of session in PostgreSQL?
In reasonably recent Postgres versions you can create a function in
pg_temp schema:
create function pg_temp.get_true() returns boolean language sql as $$ select true; $$;
select pg_temp.get_true();
This is the schema in which temporary tables are created. All its
contents, including your function, will be deleted on end of session.
You can also create triggers using temporary functions on tables. I've
just tested this and it works as expected:
create function pg_temp.ignore_writes() returns trigger language plpgsql as $$
begin
return NULL;
end;
$$;
create table test (id int);
create trigger test_ignore_writes
before insert, update, delete on test
for each row execute procedure pg_temp.ignore_writes();
Because this trigger function always returns NULL and is before [event] it should make any writes to this table to be ignored. And
indeed:
insert into test values(1);
select count(*) from test;
count
-------
0
But after logout and login this function and the trigger would not be
present anymore, so writes would work:
insert into test values(1);
select count(*) from test;
count
-------
1
But you should be aware that this is somewhat hackish — not often used
and might not be very thoroughly tested.
That's not how it works. CREATE TRIGGER requires that you either own the table or have the TRIGGER privilege on it (which nobody in their right mind will give you, because it enables you to run arbitrary code in their name). Moreover, CREATE TRIGGER requires an SHARE ROW EXCLUSIVE lock on the table and DROP TRIGGER requires an ACCESS EXCLUSIVE lock, which can be disruptive.
Create a single trigger and keep that around.
Good evening . I'm working on a chat application using nodejs, prisma, postgresql. I would like 24 hours after the last message is created on a specific chat to be immediately deleted from the postgresql database. For this, I created a trigger:
--function creation
create or replace function chat_expired() returns trigger as $delete_account$
begin
delete from chat where current_timestamp - last.messages.createAt = 24*60*60;
return new;
end;
$delete_account$ language plpgsql ;
-- trigger creation
create trigger messages_added
after update
on chat --I get error on this line
for each row
execute procedure chat_expired();
from postgresql query tool but when I execute I get the error the cat relationship does not exist at the trigger definition level. I guess it's because the chat table hasn't been defined in my query tool space; but I didn't set it because the chat table was already created from prisma immigrations. So I deleted the folder of my prisma migrations, then I created a new migration and I modified the .sql file manually in order to insert my trigger there thus thinking that prisma would also create a trigger for me at the same time as database tables:
--function creation
create or replace function "chat_expired"() returns trigger as $delete_account$
begin
delete from "Chat" where current_timestamp - last.chatMessage.createdAt = 3*60;
return new;
end;
$delete_account$ language plpgsql ;
-- trigger creation
create trigger "messages_added"
after update
on "chat"
for each row
execute procedure "chat_expired"();
Notes: The previous code contains a few more quotes than the first code. But it instead prevented the migration from applying and I got the error
Error: P3006
Migration `20220905231003_initial_migration` failed to apply cleanly to the shadow database.
Error code: P1014
Error:
The underlying table for model `(not available)` does not exist.
which was only resolved after I removed the manually added rows. So I don't know how to create a trigger on a postgresql database managed by prisma. I've been thinking about the solution for several weeks. I even looked at this stackoverflow question and also this one but nothing. Thanks !
Prisma doesn't have support for triggers yet. Prisma has an excellent article on the topic. They advice writing Prisma middleware to achieve "triggers". There is also a feature request for it.
I would like to know if a trigger on a system table of PostgreSQL can be executed when I create a table
I need to add 2 functions on each table of my database and I would like to do it dynamically
Thanks
This can be done with an event trigger:
CREATE OR REPLACE FUNCTION on_create_table_func()
RETURNS event_trigger AS $$
BEGIN
-- your code here
END
$$
LANGUAGE plpgsql;
CREATE EVENT TRIGGER
on_create_table ON ddl_command_end
WHEN TAG IN ('CREATE TABLE')
EXECUTE PROCEDURE on_create_table_func();
Note that there is no way to directly execute any query on the newly created table, or even get its name.
I don't know what you mean by "add 2 functions on each table" since functions don't belong to a specific table, but if you need to perform an operation specific for the new tables, this might not be for you.
I know it's an old question but now it has been implemented in version 9.3, or at least partially
http://www.postgresql.org/docs/9.3/static/event-trigger-definition.html
You're looking for "DDL Triggers". They're not implemented in PostgreSQL. Neither you can add triggers to system tables. Look at this forum entry:
Adding ddl audit trigger
Hi I am trying to figure out the syntax for triggers. I have two tables one called tagged_in and the other notification. So I want to make a trigger where when an insert is called in tagged_in I want to insert a tuple in notification.
The manuals are available at the DB2 InfoCenter. Did you read the CREATE TRIGGER statement information yet? If not, why not? If so, what did you try, and what error did you get?
Something like this
CREATE TRIGGER TEST_TRIGGER
AFTER INSERT ON TAGGED_IN
REFERENCING NEW AS NEW_TAG
FOR EACH ROW
BEGIN ATOMIC
INSERT INTO NOTIFICATION
VALUES (NEW_TAG.FIELD1,NEW_TAG.FIELD2);
END
Is this possible?
I would like to have a limit for a user, lets say 5 databases.
So when he tries to issue a CREATE query to create a 6th an exception is thrown.
No, you cannot do this - at least not in a declarative way (just simply specify the max number of databases owned for each user).
The closest you could get with standard SQL Server functionality would be to create a DDL trigger for CREATE DATABASE and in that trigger, check to see if the current user already owns five databases, and in that case, let the trigger fail the operation.
Something along the lines of this (taken from TechNet sample):
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
-- here, check to see if current user already owns five databases
-- and if so, fail the trigger by using RAISERROR
GO
look into DDL triggers, with a trigger like this one below you can trap the CREATE DATABASE statement
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
--do something here
-- select count(*)from sys.sysdatabases where sid = ???
GO