Trigger for insert problem - sql

I'm using mssql server 2008 and having a problem with a trigger. Now, i have this aspx page, which has a stored procedure working in a button click, and that stored procedure has an execute permission for the user, lets says "x". this procedure insert some values to a table on one db. and that table has a trigger for insert, which should insert those values to some tables at other databases.
As i said, the stored procedure has an execute permission for the user "x", and the same user have insert/update/delete/select permissions on the tables that the trigger should do the insert to.
But when someone with an "x" permission starts the procedure, he/she gets this exception message : Cannot find the object "DatabaseName..table_name" because it does not exist or you do not have permissions.
But i know that database and table name is correct.
So i am thinking, maybe it has something to do with the table having permissions but i am not sure of course.
Any help with be appreciated, thanks.

Maybe you have same tables with different schemas? Your message doesn't indicate schema used.
Or your user has not other database access right? It is actually possible that user has rights to table, but his access to database itself is disabled.

Related

specific permissions to a table based on user

I am using SQL Server 2012.
I have a table which contains two columns. One is called Directory, the other UserName.
To explain my problem I think a simple example is easier.
So this table has 3 users. In the UserName column, only the 3 users, usernames can be entered plus one other entry called Default.
Directory UserName
C:\Blah Bob
C:\BlaF Brad
C:\BlaK Dave
C:\BlaPP Default
C:\Anoth Default
What I would like to know is if it is possible to allow only two of the users to be able to insert, delete records with the username Default and the other user to be able to only select the records with Default.
Is this possible?
Update
After doing some reading is it not possible to do this using an Instead of trigger? So in my understanding this trigger will fire before an insert, update or delete query is executed. So I was thinking in the trigger if could check the host pc (users on my team will only be using their computer) to see who it is trying to insert, update or delete and if its a user who doesn't have permission to edit the default list then exit the trigger and don't update the table. Or am I missing something?
Instead of giving users direct access to the table, give the first two users access to a stored procedure that inserts to the table, and only inserts "Default" for the username.
Give the third user access to a view (or stored procedure) that only selects records where username="Default".

Target tables in different schemas from store procedure but don't change code

Please can any one advise if it is possible to have a stored procedure in the [dbo] schema select data from one table in one schema for users accessing via one database role and for it to select data from a like-named table in another schema for users accessing via another database role?
For example if I have three schemas in my database:
dbo
green
red
I have two database logins [RedLogin] and [GreenLogin]. These connect to my database using respective database users [RedUser] and [GreenUser]. These users are members of the respective database roles [RedRole] and [GreenRole].
[RedUser] has a default schema of [red].
[GreenUser] has a default schema of [green].
[RedRole] has execute permission on [dbo] and select permission on
the [red] schema.
[GreenRole] has execute permission on [dbo] and select permission on
the [green] schema.
In the [green] schema I have a table called [User].
In the [red] schema I have a table called [User].
In the [dbo] schema I have a stored procedure called [User_GetAll]
that runs.
SELECT * FROM USER;
What I would like is:
For users who login with [Redlogin] and call the
[User_GetAll] get all users from the [red].[User] table.
For users who login with [Greenlogin] and call the
[User_GetAll] get all users from the [green].[User] table.
So I have a question. For example:
-[dbo] schema in the past, I had 100 stored procedures. And now, I don't want to change code in stored procedure because It's so much, so How can I do to address the problem? Please help me.
....................................................................................
Update:
For simple example:
I have a schema [dbo], and in that schema, I have created a stored procedure dbo.GetAccount:
CREATE PROCEDURE dbo.GetAccount
AS
BEGIN
SELECT * FROM tblAccountNet
END
Then, I have created a schema [ABC] with user named UserABC.
Now, I would like to login with UserABC and execute dbo.GetAccount for schema [ABC] to get all user of it and don't want to change code of dbo.GetAccount. So, how can I do?
These are my ideas to resolve it:
Create another stored procedure in [dbo] schema, and use it to read all other procedure to make them execute against schema with user when login. Can I do that? So, how can I do that?
Create a stored procedure to change schema of all [dbo] procedure to [ABC]. Can I do that?
Thanks for your help.
Your best bet here would be to use dynamic SQL. That is something which allows you to pass string variables into a script which then gets executed against the SQL engine. For example, if you had variables #dynamicsql and #usertype, you would build a dyanmic SQL string like:
#dynamicsql = 'SELECT * FROM '+#usertype+'.tblAccountNet'
Then you would execute this code in a stored procedure using EXEC(#dynamicsql). This would probably work, but it requires additional permissions for the user, and also opens you up to a whole world of security concerns, with the biggest one being SQL Injection attacks. So this would probably work, but it might be more trouble than it is worth.
http://xkcd.com/327/

Trigger and stored procedure security in SQL Server

I have a database (SQL Server) that is being used by 20 users, all members of the same security role. The role enables them to insert, delete and update to Table1, but they have no permissions for Table2.
Table1 has a trigger that fires a stored procedure, Table2_Refresh, that truncates Table2 and rebuilds it from Table1.
I have read in some places that the trigger and stored procedure automatically execute as the caller, and therefore uses the caller's permissions. However 19 of the 20 users are able to update Table1 and the trigger and SP execute fine. One user gets an error telling him that Table2 cannot be found.
I know I can put an 'EXECUTE AS' line in the SQL, but this is happening in multiple places, and it seems like it is an issue with the user, so I would like to solve it there if possible. Since the role memberships and permissions are identical, are there any other reasons why two users would be experiencing different behaviour from the database?
The role and permissions are clearly not identical...
Are they logging in the same way (e.g. are they all using Integrated Security)?
I suggest to check the default schema of the database user used by that special login.
If the table schema is dba but the default schema of the database user is dbo, querying the table without specifying the schema will fail.

Facing an error : table or view does not exist

I am using insert statement and trying to insert data into the database table. I am using stored procedures.
But I am getting this error while doing so.
Message: ORA-00942: table or view does
not exist ORA-06512
I checked if the tables/stored procedures are present or not and everything is in place. Also there is no typo in table names or in sp. If I run the part of SP from query editor it works fine but when I execute the entire SP it throws an error.
I tried the steps provided by Stephen but since I have logged in with the same user/owner when I run Grant command it gives me an error saying 'Cannot Grant/revoke on own'.
One more addition to this. I have a stored procedure SP1 in which I am using a select statement as
Select a from table_name where condition;
When I execute this seperately, it returns me some results. But when I execute sp it gives an error at the same line where it is written.
Can anyone help me out to resolve this issue. I am using SQL +.
Thanks in advance
Vijay
Justin's answer is correct but let me expand a bit.
Everyone who said that the table doesn't exist didn't read your whole post. Since you are able to:
If I run the part of SP from query editor it works fine
Obviously the table is there.
Obviously you have some access to it. Otherwise this wouldn't work when it clearly does.
but when I execute the entire SP it throws an error.
This is because Oracle distinguishes between permissions granted directly and those granted via a role.
Say I do this:
Create Table TABLE_A
Create Role READ_ONLY
Grant Select on TABLE_A to READ_ONLY
Grant READ_ONLY to VIJAY
In a SQL Window/prompt you could query that table without issue. So now you need to create a view
Create VIJAY.VIEW_A as SELECT * FROM TABLE_A
You'll get the error that TABLE_A does exist. Because a view is compiled, like a procedure it runs without any roles. Since it runs without the READ_ONLY role, it's blind to the fact that TABLE_A exists. Now what I need to do is
Grant Select on TABLE_A to VIJAY.
Now that you have a direct permission, you can compile a view or procedure/package that uses that table.
Does the table exist in the schema where the stored procedure exists? If not, the simplest explanation is that the owner of your procedure has been granted access to the table via a role not via a direct grant. A definer's rights stored procedure needs to have direct access to the objects it accesses. A quick way to test this is to disable roles for the session, i.e.
SQL> set role none;
SQL> <<execute your query>>
If that generates the error, the problem is the lack of a direct grant.
In Oracle you can choose if the stored procedure is executed with the rights of the invoker or the definer: http://download.oracle.com/docs/cd/E11882_01/appdev.112/e17126/subprograms.htm#i18574
Check if the AUTHID property of the stored procedure is correct and if the resulting user has appropriate permissions.
Well, put very simply, the table that you are trying to insert data into does not exist in the database you are connected to. You need to check both those things (i.e. what are you connected to, and is the table there and accessible for the user context you are using).
As Joe Stefanelli said .. there are a lot of possibilities for the error being shown here.
Check whether:
You are connecting to the correct Oracle Instance.
You have permissions to query or perform processing on table that you are referencing in your query.
There is a difference between ordinary select statements and procedures. Procedures in oracle do not respect the roles assigned to a user; rather the permission needs to be explicitly granted to the user. For more information read the following linkORA-00942

Running trigger that calls stored procedure on another database

We would like to run a trigger on one database (A) that calls a stored procedure on another database (B).
CREATE TRIGGER trg_A ON TableA
FOR INSERT
AS
BEGIN
EXEC DatabaseB.dbo.stp_B
END
We would like to do this as LoginA with UserA on DatabaseA. We also have LoginB with UserB on DatabaseB.
How can we accomplish this?
Currently we get this error message
The server principal "..." is not able to access the
database "DatabaseB" under the current security context.
We have tried WITH EXECUTE AS 'UserB', without luck.
Interesting question. You nerd-sniped me. I tested a bunch of different scenarios.
These failed:
Trigger on tableA references stored procedure in DatabaseB. LoginA does not exist as a user in DatabaseB.
Trigger on tableA references stored procedure in DatabaseA that inserts into DatabaseB.dbo.TableB. LoginA does not exist in DatabaseB.
Created LoginA as a user on DatabaseB, but didn't give it any rights. Repeated test1 and test2. Both failed.
Created LoginB as a user on DatabaseA. Made sure LoginB could insert into DatabaseB.dbo.TableB. Logged into DatabaseA as LoginA, ran EXECUTE AS User = 'LoginB'. Tried to insert into DatabaseA.dbo.TableA.
The only way I could get the trigger to work was to create a user in DatabaseB for LoginA and grant permissions to execute the DatabaseB stored procedure.