Facing an error : table or view does not exist - sql

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

Related

Error during stored procedure creation in DB2 database

I am struggling with schemas while creating a stored procedure in DB2 database ( 10.5 version ).
My user name is XYZ but I have to create a Stored procedure for schema ABC.
When I am trying to execute the create procedure sql I get error message which looks like Schema related
Create procedure ABC.customInsert(
IN temp INTEGER
)
BEGIN
INSERT INTO ABC.One_Column_table VALUES ( temp );
END
Error Message:
Error:DB2 SQL error:SQLCODE:-551, SQLSTATE: 42501,
SQLERRMC:XYZ;INSERT;ABC.One_Column_table
My current schema was showing XYZ earlier. ( result of select current_Schema from sysibm.sysdummy1).
I have changed it to ABC. ( using SET CURRENT SCHEMA ABC). But still the same problem.
I am able to insert, select, create UDT etc in ABC schema but the problem exists only during stored procedure creation.
Any idea what am I doing wrong ?
Based on your error message, SQLCODE -551 means that the user "XYZ" does not have the "INSERT" privilege on the table "ABC.One_Column_table".
Since you imply that you, when connected as XYZ, can insert into the table by issuing simple INSERT statements, it is possible that you possess the INSERT privilege indirectly, via a group membership. Group privileges are ignored for SQL statements in stored procedures, functions or triggers, as explained in this IBM technote.
You have two options:
Grant the required privileges on ABC.One_Column_table to the user XYZ directly.
Create a role (using the CREATE ROLE statement), grant the table privileges to that role, then grant the role to the user XYZ.
If you are curious, such behaviour is caused by the fact that static SQL statement (e.g. in a stored procedure) authorization is checked only during compilation, and the compiled code can then be executed without additional authorization checks. Groups are maintained outside the DB2 database, by the operating system, and it is possible that group membership changes after the stored procedure is compiled and without the database security administrator's knowledge. If group privileges were effective for static SQL, it would allow users who weren't originally authorized to run particular statements (i.e. were not members of the authorized group at the compilation time) still execute those statements, thus creating a security risk.
Roles, on the other hand, are maintained within the database itself by the database security administrator and thus are part of the same security landscape.

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/

Restrict user to Stored Procedures

I need to restrict user access to SELECT, INSERT, UPDATE and DELETE, so that user should manage data only using stored procedures I provide.
So, for instance
SELECT * FROM Table1
should return
The SELECT permission was denied on the object 'Table1'
however, if there is stored procedure SelectTable1 defined as
CREATE PROCEDURE SelectTable1
AS
BEGIN
SELECT * FROM Table1
END
(the real one contains filtering and parameters, so it is not meaningless, like the one above)
user should execute it successfully and get the resultset.
But obviously, I have no success implementing this set of permissions. Can anybody point me to some specific tutorial? MSDN was not very helpful.
Database is SQL Server 2012 and all objects (tables and stored procedures) are in custom schema.
You can do it using GRANT EXEC either on specific procedures or on schemas or on a database.
The following example grants EXECUTE permission on stored procedure
HumanResources.uspUpdateEmployeeHireInfo to an application role called
Recruiting11.
USE AdventureWorks2012;
GRANT EXECUTE ON OBJECT::HumanResources.uspUpdateEmployeeHireInfo
TO Recruiting11;
GO
Thanks to Igor I've got to the right MSDN page, and followed rights links.
However, using ownership chains suggested was too complicated for me, so I used
WITH EXECUTE AS OWNER
on my stored procedures and that works very good. When I log on using restricted user I see only procedures, no tables at all and I can execute procedures, but not even select from tables.
Also, I want to mention this concept is very similar to setuid and thus was familiar to me.
I mark Igors reply as answer, because ownership chains seem to be more generic way, just wanted to share info I found.

Multi-schema select statement doesn't work in PL/SQL procedure?

I'm trying to create a procedure to run multiple PL/SQL statements, but I haven't gotten very far. The select statement works fine if I run it out of a procedure, but if I try to execute it inside one -- it can't find the shttran table. I'm guessing it might be a schema issue, but I have no idea how-to correct. Ideas?
CREATE OR REPLACE PROCEDURE REGREPORTUSER.findUnsent
IS
BEGIN
INSERT INTO regreportuser.maltran (maltran.maltran_key,
maltran.maltran_sent)
SELECT shttran.shttran_id || shttran.shttran_seq_no AS maltran_key,
'No' AS maltran_sent
FROM saturn.shttran -- This is the table it can't find
WHERE TO_DATE (shttran.shttran_activity_date) > SYSDATE - 14
AND shttran.shttran_user = 'WWW2_USER'
AND shttran.shttran_id || shttran.shttran_seq_no NOT IN
(SELECT maltran.maltran_key FROM regreportuser.maltran);
END findUnsent;
Most likely, the problem is that the user that owns the stored procedure, REGREPORTUSER has access to the table saturn.shttran via a role rather than as a direct grant. A definer's rights stored procedure cannot use privileges that are granted to a definer via a role. It can only use privileges granted directly.
You can verify that this is, in fact, the problem by disabling roles in your SQL*Plus session. If you run the command
SQL> set role none;
and then try to execute the SQL statement, you should get the same error. In order to fix the problem, you need to give the grant directly
GRANT SELECT ON saturn.shttran
TO REGREPORTUSER

Cannot find table v$parameter in Oracle

I want to get the number of sessions in Oracle using the SQL query:
SELECT value FROM v$parameter WHERE name = 'sessions'
But I get this error:
Error starting at line 1 in command:
SELECT value FROM v$parameter WHERE name = 'sessions'
Error at Command Line:1 Column:18
Error report:
SQL Error: ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
Maybe the Oracle user that I use is not privileged?
Generally the better approach is to use a procedure and grant the necessary privileges to this procedure. However if you want use SQL directly, you can grant SELECT_CATALOG_ROLE or SELECT ANY DICTIONARY to the user.
Probably. To grant the rights, you need to use the table name as V_$PARAMETER. It comes from some restriction when granting rights on dynamic views.
If you want to use SQL directly (referring to the second option in the accepted answer)
As of Feb 2023, using Oracle version 19, this works...
Connect as SYSTEM and run
grant SELECT ANY DICTIONARY to <user>;
But SELECT_CATALOG_ROLE didn't work for me...
grant SELECT_CATALOG_ROLE to ...;
There are documented differences between the two here:
http://www.petefinnigan.com/weblog/archives/00001461.htm
This is where the author gives the following info and warning:
Well, SELECT_CATALOG_ROLE allows access to some things Oracle deemed not allowed by SELECT ANY DICTIONARY so we need to be careful of granting this role on these grounds. BUT, the overwhelming issue for me is that SELECT_CATALOG_ROLE gives access to 4539 objects and SELECT ANY DICTIONARY gives access to 6228 objects (both numbers in 18c XE)
I am not sure why Oracle do not publish the full list of exclusions in SELECT ANY DICTIONARY but they do publish all of the main tables. We can easily find out anyway. For me, i want to know what does SELECT ANY DICTIONARY really mean. I want to know what i am actually granting if I give out that privilege; well it means access to 6228 tables and views in 18cXE
Both of these rights should not be used; they are a sledgehammer to crack a peanut. If someone needs access to V$SESSION or V$DATABASE and there is a legitimate reason to have that access then grant access on the individual views not SELECT ANY DICTIONARY or SELECT_CATALOG_ROLE.
using the privileges: - select any table, alter any table when running the grant as SYS with SYSDBA in Oracle 12c solved the issue for me.