ORA-00904: "DBMS_METADATA"."GET_DDL": invalid identifier - sql

I get the ORA-00904: "DBMS_METADATA"."GET_DDL": invalid identifier error when I run dbms_metadata.
That error is for having the wrong column name or alias. I am not sure why I am getting it.
Here is some code to show the error: I create a table:
create table test_table (
column1 varchar2(300));
I insert a row of data:
insert into test_table values (55);
I try to get the DDL for it:
SELECT DBMS_METADATA.GET_DDL('TABLE','test_table') FROM dual;
Here is the error:
>> SELECT DBMS_METADATA.GET_DDL('TABLE','test_table') FROM dual
*
Error at line 1
ORA-00904: "DBMS_METADATA"."GET_DDL": invalid identifier
I checked permissions and it appears I have the correct permissions:
select * FROM DBA_ROLE_PRIVS where granted_role = 'SELECT_CATALOG_ROLE';
My user (aka schema) is in that list.
Here are, what I believe, the docs: https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_metada.htm#i1016867

Run this command as SYS:
grant execute on sys.dbms_metadata to public;
Granting access to your specific user may have solved your current problem, but that package really needs to be available to the entire system. Many third party programs depend on DBMS_METADATA. By default that package should be granted to PUBLIC.
Some old versions of the STIG (Secure Technical Implementation Guidelines, which almost every auditor uses as the basis for their security scripts), would revoke access from public packages. But that was a stupid idea even 10 years ago, and it's not in the current STIGs anymore anyway.

Related

ORA-00903: invalid table name when selecting from USER

I have a task of connecting to a legacy Oracle 9i database and validate users with the new ERP, however when I try to run the query, I get ORA-00903: invalid table name
This is the naive query I am starting with: SELECT * FROM USER. The table does exist, and I can view it's content using an "in-house database browser" made by some company that no longer exist and to which I do not have the source code for.
Obviously, SELECT * FROM ALL_USERS is not what I want, etc.
The point is to validate that some user credentials are valid, the most fundamental concept of authentication, against a table called "USER", with two fields: USER_NO and PASSWORD (all values stored in plain text (... yeah... I know).
user is a reserved keyword. If you want to use that for a table name you have to quote it (which you already had to do when creating it)
select *
from "USER";

how to grant execute to pgcrypto digest function to user

Using postgresql 9.6
I enabled pgcrypto using create extension pgcrypto using the postgres user.
Now i want to grant execute rights to my other db user. Unfortunately i am not able to do it. Is this possible or do you have to be a superuser to use the digest function from pgcrypto.
postgres=# GRANT EXECUTE ON FUNCTION digest TO another_user;
ERROR: syntax error at or near "digest"
LINE 1: GRANT EXECUTE ON FUNCTION digest TO another_user;
Using the answer below, I was able to successfully grant permission to execute the function. However another_user cannot execute the function. Are there other permissions that i need in order to execute this function using another_user?
another_user=> SELECT digest('whatisgoingon'::text, 'sha256'::text);
ERROR: function digest(text, text) does not exist
LINE 1: SELECT digest('whatisgoingon'::text, 'sha256'::text);
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Even though when i check permissions for the user i get back that i have permissions.
postgres=# select has_function_privilege('another_user', 'digest(text, text)', 'execute');
has_function_privilege
------------------------
t
(1 row)
Thanks
Postgres supports overloading, i.e. multiple functions with the same name but different argument lists.
When calling the function in SQL, it figures out which version you meant based on the number of parameters and their types. But when referencing the function in a DDL command (DROP, ALTER, GRANT, etc.), you need to specify exactly which version you meant, by including a list of argument types after the function name.
This is quite relevant in the case of digest, because there are actually two versions, and you need to make it clear which one you're talking about. So either:
GRANT EXECUTE ON FUNCTION digest(text,text) TO another_user
...or:
GRANT EXECUTE ON FUNCTION digest(bytea,text) TO another_user
(...or both.)
As of Postgres 10, you're allowed to omit the argument list when the function is not overloaded. This doesn't help you much in the case of digest, but at least you get a more informative error message:
postgres=# GRANT EXECUTE ON FUNCTION digest TO another_user;
ERROR: function name "digest" is not unique
HINT: Specify the argument list to select the function unambiguously.
As for your follow-up question regarding the function does not exist error, try schema-qualifying the function name, e.g. SELECT my_schema.digest(...).
If that works, it's a search path issue. You can either continue calling it with an explicit schema name, or update your search_path.
If it responds with ERROR: permission denied for schema my_schema, then you just need to GRANT USAGE ON SCHEMA my_schema TO another_user.
If it still says function my_schema.digest(text, text) does not exist, then you've probably connected to the wrong database by mistake.

PLS-00201: identifier UTIL_FILE must be declared

I'm trying to export data from a query into a csv file from Oracle Enterprise Express installed on a Windows Server 2008 machine.
I've found this solution:
http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:235814350980
which basically writes a function and uses the UTIL_FILE object to create and write to a file and add delimiters.
I receive the follow error when I try and create the function in Oracle SQL Developer:
PLS-00201: identifier UTIL_FILE must be declared.
When I run the following command:
select owner, object_type from all_objects where object_name = 'UTL_FILE'
The result is:
OWNER Object Type
--------- -----------
PUBLIC SYNONYM
EDIT:
Running:
GRANT EXECUTE ON UTL_FILE TO PUBLIC
Gives:
Error starting at line 2 in command:
GRANT EXECUTE ON UTL_FILE TO PUBLIC
Error report:
SQL Error: ORA-00942: table or view does not exist
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
What is the problem?
Seems like lack of privileges to me. Often PUBLIC user has EXECUTE privilege granted on that package, but the privilege may be revoked.
You can check if PUBLIC has that privilege by issuing the following query:
SELECT * FROM all_tab_privs WHERE grantee = 'PUBLIC' AND table_name = 'UTL_FILE';
If there are no rows returned, try granting the execute privilege to either the user you are logged as, or to PUBLIC, as some privileged user, for example SYS:
GRANT EXECUTE ON SYS.utl_file TO user_name;
Edit
You must grant the privilege while being logged as, for example, SYS user.
Users do not have execute permission on UTL_FILE by default. To use UTL_FILE, an ADMIN user or instance administrator must explicitly GRANT EXECUTE permission on it, such as in the following example:
GRANT EXECUTE ON SYS.UTL_FILE TO scott;
Aside from the possible lack of permissions that other answers have covered, your question says the error you get is:
PLS-00201: identifier UTIL_FILE must be declared
That suggests you've referenced UTIL_FILE, rather than the built-in package UTL_FILE, in your function. It might be an error you've introduced writing the question, of course, but you used it in the text too so maybe you have got the package name wrong in your code, if you didn't just copy-and-paste Tom's code.
You'll still need execute privileges on UTL_FILE anyway, if you don't have them already.
As user: h_djebli pointed out in his comment you need to be connected as SYS user in the first place.
To do that, you have to be in your oracle home directory :
cd $ORACLE_HOME
Then execute :
sqlplus / as sysdba
sqlplus will start in your terminal and you'll be connected as the SYS user.
You can finally write the GRANT command in your sqlplus console :
GRANT EXECUTE ON SYS.utl_file TO your_db_username;
We can do this via cmd, with these steps:
Login as sysdba (connect sys as sysdba + enter password as sys_password)
grant execute on utl_file to <user_name>.
now we can check by query :'SELECT * FROM all_tab_privs WHERE grantee = 'PUBLIC' AND table_name = 'UTL_FILE';'

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.

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