- Error code
- ORA-00942
- Product
- Oracle Database
- Versions
- Oracle Database 19c, 21c, 23ai and 26ai (wording differs: see below)
- Category
- Objects, Names & Identifiers
- Last reviewed
- 24 October 2026
On this page
What it means
ORA-00942 means Oracle could not find a table or view with the name used in the statement, in the schema it looked in, or the user is not allowed to see it. Oracle reports a missing object and a missing privilege the same way.
Oracle resolves an unqualified name such as orders in the current schema (normally the user you logged in as), then through private and public synonyms. If nothing matches, or a synonym points to an object that no longer exists, the statement fails with ORA-00942. In current releases the message adds the name as SCHEMA.OBJECT_NAME when one is available; 19c and 21c print only "table or view does not exist".
The error does not tell you whether the table is missing or merely hidden. Oracle's reference lists both: the table may not exist, or the user may lack the privileges needed to access it. A table in another schema that you have no privilege on is invisible to you, so it looks exactly like a table that was never created. Names are also case sensitive when they were created in double quotes: a table created as "orders" is not found by orders, which Oracle reads as ORDERS.
Inside definer's rights PL/SQL (the default for procedures, functions, packages and triggers), Oracle's PL/SQL reference states that only the role PUBLIC is enabled while the unit runs. A table you can query in SQL*Plus through a role can therefore raise ORA-00942 when the same query is compiled in a procedure; it needs a direct grant.
Common causes
- The table or view name is misspelled, or the object has not been created yet in this database or environment.
- The object is in another schema and the statement does not name the schema (and no synonym exists).
- The user has no SELECT, READ or other privilege on the object, so Oracle reports it as missing.
- The privilege comes through a role, and the statement runs inside a definer's rights procedure, function, package, trigger or view, where roles are not used.
- The table was created with a quoted lower-case or mixed-case name, such as "orders", and is referenced without quotes.
- A synonym points to a table or view that was dropped, renamed or is in a schema you cannot access.
Diagnose it
Read-only These queries only read the data dictionary (USER_, ALL_ and DBA_ views) and dynamic performance views (V$). They do not change data, privileges or settings, so they are safe to run first. DBA_ and V$ views need the matching privileges.
Who am I, and which schema are unqualified names resolved in?
SELECT USER AS login_user,
SYS_CONTEXT('USERENV', 'CURRENT_SCHEMA') AS current_schema
FROM dual; If the table lives in another schema than CURRENT_SCHEMA, an unqualified name will not find it without a synonym.
Can I see an object with this name in any schema?
ALL_OBJECTS lists only objects you can access. Comparing in upper case also reveals quoted lower-case or mixed-case names.
SELECT owner, object_name, object_type, status
FROM all_objects
WHERE UPPER(object_name) = 'ORDERS'
ORDER BY owner, object_type; No rows: the object does not exist or you have no privilege on it. A row with OBJECT_NAME in lower case (orders) means the name was created in quotes and must be written as "orders".
Does the object exist at all? (DBA)
DBA_OBJECTS shows every object regardless of privileges, so it separates "missing" from "no access". It needs DBA privileges or SELECT_CATALOG_ROLE; ask a DBA to run it if you cannot.
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE UPPER(object_name) = 'ORDERS'; A row here but none in ALL_OBJECTS means the object exists and you lack a privilege on it.
Check synonyms and grants for the name
SELECT owner, synonym_name, table_owner, table_name, db_link
FROM all_synonyms
WHERE synonym_name = 'ORDERS';
SELECT grantee, table_schema, table_name, privilege
FROM all_tab_privs
WHERE table_name = 'ORDERS';
SELECT role FROM session_roles; Where each synonym points (check that the target still exists), which privileges exist on the table, and which roles your session has enabled. A privilege that only reaches you through a role does not count inside definer's rights PL/SQL.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Qualify the name with its schema
Read-onlyIf the table is in another schema and you have a privilege on it, name the owner. This is the clearest fix and does not depend on synonyms or session settings.
SELECT order_id, order_date
FROM shop.orders
WHERE customer_id = 42;
Grant the privilege directly to the user that runs the code
Changes permissionsThe owner of the table (or a user with the right to grant it) grants only what is needed. For a definer's rights procedure, grant to the procedure owner directly rather than through a role, then recompile the procedure.
Caution: Grant the narrowest privilege that works (SELECT or READ rather than ALL) to a specific user, never to PUBLIC, and avoid ANY privileges such as SELECT ANY TABLE.
-- run as SHOP, the owner of the table
GRANT SELECT ON shop.orders TO report_app;
Use the exact quoted name, or recreate the table without quotes
Read-onlyA table created as "orders" must always be referenced as "orders" in double quotes. In new schemas, create objects without quotes so names are stored in upper case and are found whatever case you type.
SELECT * FROM "orders";
Point the session or a synonym at the owning schema
Changes configurationFor an application that always works in one schema, ALTER SESSION SET CURRENT_SCHEMA changes where unqualified names are resolved for that session only; it grants no privileges. A synonym is the permanent alternative and needs the CREATE SYNONYM privilege.
ALTER SESSION SET CURRENT_SCHEMA = shop;
-- or, once, as the application user:
CREATE SYNONYM orders FOR shop.orders;
Examples
A table created with a quoted lower-case name
Not reproduced here: no Oracle Database is installed for this site. The result follows the current message format in Oracle's error reference, which adds the name as SCHEMA.OBJECT_NAME; the schema SHOP is illustrative and the exact quoting of the name may differ by client. Oracle Database 19c prints "ORA-00942: table or view does not exist".
CREATE TABLE "orders" (
id NUMBER PRIMARY KEY,
customer_id NUMBER
);
-- unquoted names are read as upper case: ORDERS
SELECT * FROM orders;
ORA-00942: table or view SHOP.ORDERS does not exist
Querying another schema's table without a privilege
Not reproduced here: no Oracle Database is installed for this site. The result is shown in the 19c form from Oracle's error reference; current releases may add the object name. Oracle's reference lists missing privileges as one of the causes, so the same message appears whether SHOP.ORDERS is missing or simply not granted to REPORT_APP.
-- connected as REPORT_APP; the table belongs to SHOP
SELECT COUNT(*) FROM shop.orders;
ORA-00942: table or view does not exist
A procedure that relies on a role
Not reproduced here: no Oracle Database is installed for this site. The behaviour follows Oracle's PL/SQL Language Reference (a definer's rights unit runs with only the role PUBLIC enabled); the line and column numbers and the layout of SHOW ERRORS output are illustrative. A direct GRANT SELECT ON shop.orders TO report_app fixes it.
-- REPORT_APP can query SHOP.ORDERS through the role REPORTING,
-- but definer's rights PL/SQL runs with roles disabled
CREATE OR REPLACE PROCEDURE count_orders AS
n NUMBER;
BEGIN
SELECT COUNT(*) INTO n FROM shop.orders;
END;
/
SHOW ERRORS
LINE/COL ERROR -------- ------------------------------------------- 5/5 PL/SQL: SQL Statement ignored 5/33 PL/SQL: ORA-00942: table or view does not exist
How to prevent it
Qualify cross-schema references with the owner, or create synonyms as part of the deployment, and grant application users the exact privileges their code needs directly rather than through roles. Create tables without double quotes so case never matters.
Run deployment scripts in a fixed order (tables, then views, synonyms and grants, then PL/SQL) and check after each release that every synonym still points to an existing object. In application logs, record the connected user with the error: most ORA-00942 reports turn out to be "right SQL, wrong user".
Common questions
How do I fix ORA-00942 table or view does not exist?
Check the spelling, then query ALL_OBJECTS for the name. If it is in another schema, qualify it (SHOP.ORDERS) and make sure you have a privilege on it; if it was created in quotes, use the exact quoted name; if it does not exist, create it or connect to the right database.
The table exists, so why does Oracle say it does not?
Usually because you have no privilege on it, the name is in another schema, or it was created with a quoted lower-case name. Oracle reports a table you cannot access in the same way as a missing one.
Why does my query work in SQL*Plus but not in a stored procedure?
Your privilege comes through a role. Definer's rights PL/SQL runs with only PUBLIC enabled, so the procedure owner needs a direct grant on the table, or the unit must be declared AUTHID CURRENT_USER.
Learn more on CodeWithSQL
Official documentation
- ORA-00942 (Oracle Database Error Messages)
- Database object names and qualifiers (Oracle SQL Language Reference 19c)
- Invoker's rights and definer's rights (Oracle PL/SQL Language Reference 19c)
- ALL_OBJECTS (Oracle Database Reference 19c)
Last technically reviewed 24 October 2026; examples and diagnostics run on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally. Messages and explanations follow Oracle's Database Error Messages reference; no Oracle Database was available, so the examples were not run locally.