Not able to access DBA_DIRECTORIES table.Getting an error message that table or view does not exist.
DBA said that he has given access to user however, still getting an error. I'm able to see result from ALL_DIRECTORIES but not from DBA_DIRECTORIES. Please guide on this.
Why would any user (but a DBA) have access to DBA_DIRECTORIES?
Users should have privileges to access those directories, i.e. should be granted read and/or write privileges so that they could
read files and use them as external tables
create files using UTL_FILE
export their tables using data pump
and similar. But - access to DBA_DIRECTORIES itself? I don't think so.
Access to a database directory is done in two steps:
-Database permission : The user must have read and if necessary write privilges over the directory. You can check this by this query
select * from all_tab_privs where table_name = 'YOUR_DIRECTORY' ;
-If your user has the privileges read and write granted over the directory, but still you are getting errors using UTL_FILE, then perhaps the problem is in the physical location of the directory itself. You must check the privileges of the directory_path in the server
select directory_path from all_directories where directory_name = 'YOUR_DIRECTORY' ;
Get the path from the above query, go to the server and check that the operating system user who owns the oracle software has read and write privileges over that folder ( normally is oracle in Linux servers )
You don't need access to DBA_DIRECTORIES, that is only for administrative purposes, as all the DBA views are. You have more than enough with your ALL_DIRECTORIES view
I think we are talking two different things here , having access to directory doesn't guarantee we have the access to dictionary view such as DBA_DIRECTORIES.
See Question answer
Please read here
Check now if you have these rolee.
Related
My questions is as follows:
I am trying to create a script which will execute in sqlplus and what this script will do is that i will have a file in which you can write inside 1 name on every line. So i wanted to use an Associative Array in which i will read the contents of the file line by line (1 name on every line) and store every name in the array.
My problem is that i cannot use the UTL_FILE package which has a ready GET_LINE procedure to get the name of every line because it has to take as argument a "Logical Directory" of Oracle.
My issue is that i cannot make changes to the database like to create a new directory or use one of the default directories for the in file. I have to come to a solution in which i will read the contents of the file from a physical location.
I am kindly asking for some assistance in 2 fields. If you can please help me if you know any other package which can work on a physical location or if know any other way in which maybe i can call sqlplus (sqlplus username/pass #myscript) and give there as an argument the input file or like initialize the array from there.
Thank you in advance.
Any help would be highly appreciated
George
Clearly the best solution is to use UTL_FILE or external tables. So not being able to change the database is a major problem. If you don't have the permission to create a directory object and you cannot persuade a privileged user to do so on your behalf, then your question basically becomes
"How can I circumvent the security restrictions imposed on the database?"
Well, there are two possibilities.
If the DBAs have been careless enough to enable the UTL_FILE_DIR parameter in the init.ora file you may still be able to use UTL_FILE, by passing an absolute file path to FOPEN().
Alternatively, you can write a Java Stored Procedure to interact with files on the OS. This requires privileges to be granted through the Java security model. Find out more. Again, you will only have this without asking if you have lax DBAs.
Let me make it clear, both these "solutions" are grey hat. You really should try to get the necessary privileges through the proper channels. If the DBA team won't create a directory are you can use you need to escalate it to your boss.
If you cannot make any change to the database and the existing database does not provide you the privileges you need, you're out of luck.
UTL_FILE either requires the presence of an Oracle directory object that points to a physical directory on the database server that you have privileges on or that you are using a physical directory that you have been given access to via the deprecated UTL_FILE_DIR parameter. It appears that you are stating that neither of these is a viable option. If that is the case, you cannot use UTL_FILE.
You could also create an external table that would read data from a file. That would require that you could create the Oracle directory object and the external table. Again, it sounds like you are saying that is not an option so external tables are out.
You could write a Java (or .Net if you're on Windows) stored procedure that would read from the file. That would require that you create the procedure and that you grant the owner the necessary file system privileges. It sounds like you're saying this is also not an option so Java stored procedures are out.
If you move the file to the client machine, you could use SQL*Loader on the client machine to load the data into a table in the database. That would require that you create a physical table in the database, though, which it sounds like you are saying is not possible. So SQL*Loader is out.
If you can move the file to the client, you could obviously write a program in whatever language you would like to read the file and build whatever PL/SQL block you'd like. But that won't work for files stored on the database server barring some sort of very odd permissions grants where your client machine can somehow mount a directory on the server.
So we're back to where we started. Reading a file from the server's operating system requires privileges to be able to read that file. You seem to be saying that you do not have and cannot get those privileges. Therefore, you're saying that you can't do what you want. Whoever in your organization is asking you to implement this change needs to talk with whoever is preventing you from getting the privileges you need to do your job. One of them needs to give ground.
I want to create the user and the database within that user. But when I tried to create database its giving the warning message as
ERROR at line 1:
ORA-01501: CREATE DATABASE failed
ORA-01100: database already mounted
Then I tried
STARTUP NOMOUNT;
Its giving the warning message for insufficient privileges even I have given all the permission to that particular user.
Can any one please help in finding the solution for this?
You don't create a database under a user in Oracle; I believe you're using terminology from another database poduct. The equivalent is a schema, which is a logical container for a group of objects. User and schema are essenentially synonymous in Oracle - when you create a user is automatically has its own schema.
You create the database once (which you already seem to have done, or had done for you), then create as many schemas/users as your application needs. You don't ever rerun the create database under normal circumstances - you certainly wouldn't as a normal user.
If you connect as that user you will be able to create tables, views, packages etc., assuming it has really been granted all the necessary privileges.
I have a oracle external table. There is a oracle directory created for use of external table to read input CSV file. DISCARD, LOG and BAD files of external table will be created in the same directory.
When corresponding directory on unix has permissions "1770", external table can not read or write from that directory. When permissions for that directory are changed to "1777", external table is able to read write into that directory.
I am not able to figure out what is the issue when permissions for that directory are 1770. Please provide me with any hint on this weird behavior.
Please note that oracle schema user has READ and WRITE grants on that directory.
What user and group owns the operating system directory? What operating system user runs the Oracle database? What group(s) is that operating system user that runs Oracle in?
It sounds from your description that the operating system user that runs Oracle does not own the operating system directory and is not part of the group that owns the directory. In Unix, privileges on a directory are granted to the user (the first 7), the group (the second 7), and to the public (the third digit, either a 7 or a 0 in your example). If changing the privileges associated with the public are changing the behavior, that implies that the Oracle operating system user only has the privileges granted to the public on this directory.
I have access to the Oracle 10g database, but not the Unix server. I would like to verify that a file exists on the server. Is there a way to use the "ls" command to view the contents of a directory on the Unix server? I don't think this is possible, but I want to be sure.
Note the file is located in a "directory" defined in the dba_directories view and my Oracle user (myusername) has Oracle read / write access to the "directory". This can be verified by looking at the dba_tab_privs view.
You can't do it from pl/sql but you can do it with java. There is an ask tom article that contains the java code at this link.
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:439619916584
I am trying to open an existing physical file from file system in a procedure in Oracle 10g. The bfilename function requires a directory and path. I want to pass on the directory such as "c:\abc" directly to the procedure, i.e. I don't want to pass a directory object. The reason is, the directory can change, and I don't know how to create or replace directory inside a procedure (the command always returns error saying that variable is not allowed). I also am not sure about how it works in a multi-user environment, because a new directory is not local to the procedure.
When I run the command:
bfilename('c:\abc', 'myfile.txt');
it returns error that directory do not exists. I have checked by ending directory with "\" i.e. make it "c:\work\". I have also checked by capitalizing the directory name inside the procedure. If I make a directory object say DOCUMENTS and pass it to the bfilename, then its working.
bfilename('DOCUMENTS', 'myfile.txt');
Is there some way to make the directory part dynamic?
Update: I have tried to create directory from inside the procedure because this msdn article says that directory-object is must. The code is as follows:
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY WORKDIR AS ''c:\work''';
The procedure compiled successfully but when run gives following error:
Insufficient privileges.
I have only one user in my test database, this user has sysdba role. I have physical access to file through file system. The database-user can create directory through sqlplus.
Mark's answer solves your specific problem (you cannot use privileges gained through the SYSDBA role in procedures) but I want to discuss the underlying issues.
The relevant privilege is CREATE ANY DIRECTORY. All directory objects are owned by SYS, which is why this is a privilege which should be granted with caution.
Bear in mind that the second time you run your stored procedure it will fail. This is because the directory already exists. There is no ALTER DIRECTORY syntax. This means you need to drop and re-create the directory every time you want to change its path. Consequently you will also need to grant DROP ANY DIRECTORY to the user. Also, in a production environment you would need to re-issue the privileges granted on that directory to any other users who need it.
Why do Oracle make it so hard to work dynamically with directory objects? Because we shouldn't need to do it.
The OS directory structure is full of potential dangers for the database. Access to OS files from inside the database should be strictly controlled. That means we should specify particular directories for known purposes (DataPump, writing dumps and logfiles, importing CSV files, etc) and stick to them. Allowing procedures to change the paths of directories on the fly is a red flag for bad business process.
But, sometimes directory objects are a real pain. For instance, I once worked on a system which generated millions of files. In order to spread them across the operating system without blowing the unix inode limit we had a tree structure based on the last two digits of the header ID and the penultimate two digits of the header ID. Some like this:
$OUT_FILES/whatever/00/00
$OUT_FILES/whatever/00/01
...
$OUT_FILES/whatever/99/98
$OUT_FILES/whatever/99/99
That would have been ten thousand directory objects per feed. Which is a lot. So we used the (deprecated) UTL_FILE_DIR parameter. This parameter is deprecated for at least three reasons:
It is set in the INIT.ORA file and changing it requires a database re-start.
There is no granularity. Every database user has privileges on any OS directory in the list
The security is laxer because it allows wildcards.
Also, it means we have to specify the full OS path whenever we need to read or write to a directory, which is fragile and error-prone.
However, if you're working on a toy database this parameter might solve your headache. Find out more.
Just to be clear, I am not recommending that anybody use this parameter in a proper database unless they really understand the limitations. In most situations directory objects are safer and more convenient.
Try granting the 'CREATE DIRECTORY' privilege directly to the user (i.e., not through a role).
Something like:
grant create directory to the_user;
The reason for that is that roles are disabled inside of stored procedures. So, your user needs a direct grant explicitly granted.
Hope that helps.