Query to disable triggers for a particular user in Postgres - database

Here is the query to disable all triggers in a particular table:
alter table plan_items DISABLE TRIGGER ALL
But I'm getting access issues while executing the query. How do we execute the same query passing for a particular database user? I want to delete triggers that are only part of the mentioned database user.

You can configure a user so that ordinary triggers won't fire for it:
ALTER ROLE myuser SET session_replication_role = replica;

Seems like the below query does the exact job:
ALTER TABLE table DISABLE TRIGGER USER;
This will disable normal triggers added by the database user.

Related

Alter table to disable trigger in stored procedure

If we have an alter table statement within a stored procedure. Will it just affect that session or will it affect all sessions?
We use the alter table to disable the triggers that occur because we don't want them run when the stored procedure occurs but want the update triggers to run at all other times.
Cheers,
"Alter table" is an DDS operation - it will change the DB structure for all connections.
Here is a trick: create temp table with unique name like #no_triggers_for_[procname] at the beginning of your sp and check for it's existence within triggers.

Sql server deny drop view to role

I use SQL Server 2008 R2 and want to deny drop any view to developer role.
How can add deny permission for drop any view to this role.
By database Trigger can prevent drop any view for all user.
The problem here is that the deny permission applies to the following securables:
Synonyms
Tables and columns
Views and columns
So you could use:
USE dbName
GO
DENY DELETE TO [developerRole]
GO
The problem is that I assume that you will want some of the developers to be able to drop items, this will prevent anyone in the developer role from dropping any of the above securables. You could instead apply this permission directly to the user, but if you want them to be able to drop tables or columns, but not views, then it won't work either.
Another method would be to move all your views into a separate schema, then deny the user DELETE on that schema:
USE [dbName]
GO
DENY DELETE ON SCHEMA::[viewsSchema] TO [developerRole]
GO
The problem here is that it's messy and not really the best use of a schema, not really an option I would go for.
I think the best option really is a trigger, if it really is just one user you can do the following:
CREATE TRIGGER noViewDrop
ON DATABASE
FOR DROP_VIEW
AS
IF USER_ID() = USER_ID('Bob')
BEGIN
PRINT 'Bob Can''t Drop Views';
ROLLBACK
END
This means that Bob can't drop any views in the database, but can drop any of the other securables listed above. If you want to apply this to a database role rather than an individual user, simply use the IS_ROLEMEMBER() function like so:
CREATE TRIGGER noViewDrop
ON DATABASE
FOR DROP_VIEW
AS
IF IS_ROLEMEMBER ('developerRole') = 1
BEGIN
PRINT 'Members of the developerRole Can''t Drop Views';
ROLLBACK
END
Meaning anyone in the developer role will be caught by the trigger when dropping views, but if they need to drop a column they will still be able to do this. Anyone who is not in the developerRole will still be able to drop views.
Trigger
CREATE TRIGGER NO_DROP_VIEW
ON DATABASE
FOR DROP_VIEW
AS
PRINT 'Dropping VIEWs are not allowed'
ROLLBACK
To deny drop view you can simply include DENY DELETE
use Your_Database
GO
DENY DELETE TO [SQLUserTest]
GO
When user is denied DELETE permission, that user is no longer able to drop or delete any object in that database.

How can I use t-sql permissions to show someone a subset of records from a table?

I have a table with many records in Microsoft SQL Server 2008. Some of the records have boolean flag set. Others do not.
I want to a user to be able to ONLY see records where the flag is set. I made a view that uses a select statement to query these records and I gave the user read permissions on this view. But because the view selects from the original table SQL server is saying the user does not have enough permissions to look at the view.
The view and the table are in the same database.
How can I set permissions (either using a view or using some other method) so that the user can only see the subset of records from this table?
This works exactly as it should:
USE tempdb;
GO
CREATE TABLE dbo.MyFlags(a INT, flag BIT);
GO
INSERT dbo.MyFlags VALUES(1,0),(2,1),(3,1);
GO
CREATE VIEW dbo.vMyFlags
AS
SELECT a, flag FROM dbo.MyFlags WHERE flag = 1;
GO
CREATE LOGIN smudge WITH PASSWORD = 'floob', CHECK_POLICY = OFF;
GO
CREATE USER smudge FROM LOGIN smudge;
GO
GRANT SELECT ON dbo.vMyFlags TO smudge;
GO
EXECUTE AS user = 'smudge';
GO
-- from view (succeeds):
SELECT a,flag FROM dbo.vMyFlags;
GO
-- from table (error):
SELECT a,flag FROM dbo.MyFlags;
GO
Perhaps you missed a step there, or created or referenced objects without the correct schema prefix. Always, always, always use the schema prefix.

SQL Server Trigger - Need to Alter

I need to alter a trigger in SQL Server. After I am doing, do I just execute the trigger similar to how I would do for a Stored Procedure?
ALTER TRIGGER
Yes, that is right, just use ALTER. If you right-click on your trigger in Object Explorer in SSMS and select Script Trigger as/ALTER To, you will see the ALTER statement created for your trigger.
ALTER TRIGGER triggerName
ON tableName
FOR INSERT -- or update & delete
AS
-- sql here
http://msdn.microsoft.com/en-us/library/ms176072.aspx
You don't "execute" a trigger. Triggers are "triggered" at certain points depending upon your definition of them.
For example an AFTER UPDATE trigger would run for all rows updated after you send an UPDATE command to the table on which the trigger is created.

Multi-Schema Privileges for a Table Trigger in an Oracle Database

I'm trying to write a table trigger which queries another table that is outside the schema where the trigger will reside. Is this possible? It seems like I have no problem querying tables in my schema but I get:
Error: ORA-00942: table or view does not exist
when trying trying to query tables outside my schema.
EDIT
My apologies for not providing as much information as possible the first time around. I was under the impression this question was more simple.
I'm trying create a trigger on a table that changes some fields on a newly inserted row based on the existence of some data that may or may not be in a table that is in another schema.
The user account that I'm using to create the trigger does have the permissions to run the queries independently. In fact, I've had my trigger print the query I'm trying to run and was able to run it on it's own successfully.
I should also note that I'm building the query dynamically by using the EXECUTE IMMEDIATE statement. Here's an example:
CREATE OR REPLACE TRIGGER MAIN_SCHEMA.EVENTS
BEFORE INSERT
ON MAIN_SCHEMA.EVENTS REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE
rtn_count NUMBER := 0;
table_name VARCHAR2(17) := :NEW.SOME_FIELD;
key_field VARCHAR2(20) := :NEW.ANOTHER_FIELD;
BEGIN
CASE
WHEN (key_field = 'condition_a') THEN
EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_A.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
WHEN (key_field = 'condition_b') THEN
EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_B.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
WHEN (key_field = 'condition_c') THEN
EXECUTE IMMEDIATE 'select count(*) from OTHER_SCHEMA_C.'||table_name||' where KEY_FIELD='''||key_field||'''' INTO rtn_count;
END CASE;
IF (rtn_count > 0) THEN
-- change some fields that are to be inserted
END IF;
END;
The trigger seams to fail on the EXECUTE IMMEDIATE with the previously mentioned error.
EDIT
I have done some more research and I can offer more clarification.
The user account I'm using to create this trigger is not MAIN_SCHEMA or any one of the OTHER_SCHEMA_Xs. The account I'm using (ME) is given privileges to the involved tables via the schema users themselves. For example (USER_TAB_PRIVS):
GRANTOR GRANTEE TABLE_SCHEMA TABLE_NAME PRIVILEGE GRANTABLE HIERARCHY
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS DELETE NO NO
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS INSERT NO NO
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS SELECT NO NO
MAIN_SCHEMA ME MAIN_SCHEMA EVENTS UPDATE NO NO
OTHER_SCHEMA_X ME OTHER_SCHEMA_X TARGET_TBL SELECT NO NO
And I have the following system privileges (USER_SYS_PRIVS):
USERNAME PRIVILEGE ADMIN_OPTION
ME ALTER ANY TRIGGER NO
ME CREATE ANY TRIGGER NO
ME UNLIMITED TABLESPACE NO
And this is what I found in the Oracle documentation:
To create a trigger in another user's
schema, or to reference a table in
another schema from a trigger in your
schema, you must have the CREATE ANY
TRIGGER system privilege. With this
privilege, the trigger can be created
in any schema and can be associated
with any user's table. In addition,
the user creating the trigger must
also have EXECUTE privilege on the
referenced procedures, functions, or
packages.
Here: Oracle Doc
So it looks to me like this should work, but I'm not sure about the "EXECUTE privilege" it's referring to in the doc.
What you are experiencing is a feature of Oracle's security model. The entire point of using schemas is to control access to the data. The tables in my schema are mine, you cannot even see them until I grant you privileges on them.
The syntax is quite simple: the owner schema issues
grant select, insert on my_table to you
/
Alternatively an account with the GRANT ANY privilege (such as a DBA) can pass privileges on any user's objects.
grant select, insert on apc.my_table to you
/
The grantee can be either a user or a role. However, note that we can only build program units - stored procedures, views, triggers - using privileges which have been granted directly through to our user.
So, if you get the other schema owner to grant you the necessary privileges you will be able to build your trigger.
edit
When referencing an object in another schema we need to qualify the object with the schema name ....
insert into apc.whatever_table values ...
or else we need to create a synonym for it
create synonym whatever for apc.whatever_table;
I feel someone should add the obvious - the other schema's table must be qualified with the schema name or a private/public synonym is needed. I wonder if the original problem was merely a name resolution issue. If not, APC's answer is a good explanation of the Oracle security model.
You should execute this for every table and schema involved:
grant select on OTHER_SCHEMA_%.table_name to MAIN_SCHEMA;

Resources