I work with UTL_FILE. I want to create a file in 'C:\pruebaoracle'.
I create a directory with:
create or replace directory test1 as 'C:\pruebaoracle';
grant read, write on test to public;
The procedure is
CREATE OR REPLACE PROCEDURE PRUEBAFICHEROTRAZA AS
F1 UTL_FILE.FILE_TYPE;
BEGIN
F1 := UTL_FILE.FOPEN('test1','prueba.tmp','w');
UTL_FILE.put_line(F1,'Start processing file at : ' || systimestamp);
UTL_FILE.put_line(F1,'End processing file at :'||systimestamp);
-- Close file
UTL_FILE.FCLOSE(F1);
END PRUEBAFICHEROTRAZA;
When I execute the procedure I get the error:
ORA-29280: invalid directory path
How can I create the file?
Related
i have to read a file .csv that is in a directory of my virtual box oracle. In my local system windows with sql developer i want to create a procedure that read that file in the virtual box. I don't undestand how use UTL_TCP.connection and how write that procedure
Consider using External tables.
Note that prior to creating external table You must have database directory created. The location specified is then used to read files from. You can specify separators, delimiters and filenames in the DDL statement withing creation of table. Once set-up it could be queries by using standard select statement.
For example:
create directory << db directory >> as '/u01';
create table ext_filename_csv (
column01 varchar2(4000),
column02 varchar2(4000),
column03 varchar2(4000)
)
organization external (
type oracle_loader
default directory << db directory >>
access parameters (
records delimited by newline
fields terminated by ",")
location ( << db directory >>:'filename.txt')
);
Read more here:
http://psoug.org/reference/externaltab.html
I need to create an oracle directory in oracle installation folder. In my case this path is D:\app\Administrator\product\11.2.0\dbhome_1. I tried create directory ora_dir as '\', but this make reference to D:\.
Is there any way to create the directory pointing to oracle_home?
Regards.
If you're already doing this dynamically from a procedure, you could get the ORACLE_HOME environment variable (as it was set when the instance started anyway) via a Java call, but you need a separate function:
create or replace function getenv(name varchar2) return varchar2
as language java
name 'java.lang.System.getenv(java.lang.String) return java.lang.String';
/
create or replace procedure p42 as
begin
execute immediate q'[CREATE or replace DIRECTORY DIRECTORY_DIR AS ']'
|| getenv('ORACLE_HOME') || q'[']';
end;
/
Assuming both compile OK, when executed the directory is created with the path from the environment variable:
exec p42;
PL/SQL procedure successfully completed.
select directory_path
from all_directories
where directory_name = 'DIRECTORY_DIR';
DIRECTORY_PATH
----------------------------------------
/dboracle/orabase/product/11.2.0
If your procedure is in a package, the function can be in there too, privately if you prefer. And you don't need any additional privileges to use the Java call, just create procedure, which you already have in this case.
Unfortunately this doesn't work in Windows as ORACLE_HOME is set in the registry, not the environment; it may be possible to get information from the registry but you may also have more than one Oracle Home so you'd have to determine which registry key to use.
There is also (as Aramillo found) an [undocumented] built-in DBMS_SYSTEM package that can provide the same information; with that you could do:
create or replace procedure p42 as
l_oracle_home varchar2(100);
begin
dbms_system.get_env('ORACLE_HOME', l_oracle_home);
execute immediate q'[CREATE or replace DIRECTORY DIRECTORY_DIR AS ']'
|| l_oracle_home || q'[']';
end;
/
But you would need to have execute permission granted on that package, and it's undocumented status might give you pause; some of the functionality seems to be restricted to SYSDBA anyway (note 159968.1).
While poking around My Oracle Support looking for DBMS_SYSTEM references, I also stumbled over this option:
select nvl(substr(file_spec, 1, instr(file_spec, 'lib') -2),
substr(file_spec, 1, instr(lower(file_spec), 'bin') -2)) as oracle_home
from dba_libraries
where library_name='DBMS_SUMADV_LIB';
... which apparently also works on Windows, but you need sufficient privileges to see the data dictionary entries.
You need to provide the full path:
CREATE DIRECTORY ORA_DIR AS 'D:\app\Administrator\product\11.2.0\dbhome_1';
I'm trying to open file changelog.txt and I need to open it no matter what user is opening it. It's however always located in ~/ directory. Access the file. Here's my code:
procedure TForm1.FormCreate(Sender: TObject);
var myFile : TextFile;
line : string;
begin
AssignFile(myFile, '~/changelog.txt');
Reset(myFile);
while not Eof(myFile) do
begin
ReadLn(myFile, line);
Label3.Caption := (Label3.Caption + line + #13#10);
end;
CloseFile(myFile);
end;
It doesn't work. However, if I replace ~ with the actual username, it works. However, I cannot know the username of each user that will run my program. Any ideas how can I get the username of user that started the program? Thanks!
Edit1: I have tried this, but it also includes a new line:
RunCommand('/bin/bash',['-c','whoami'],user);
This is normal. "~" is a shell level concept and thus needs a separate shell invocation to evaluate. Assignfile calls the kernel interfaces directly though and thus doesn't understand this.
Use getenvironmentvariable('HOME') to get the homedir from the environment. Better even, getuserdir allows to get the home dir in a crossplatform manner.
I'm trying to execute these lines:
DECLARE
V_FILEHANDLE UTL_FILE.FILE_TYPE;
BEGIN
V_FILEHANDLE := UTL_FILE.FOPEN('C:\samples', '1.csv', 'w');
UTL_FILE.PUT_LINE(V_FILEHANDLE, 'sample string');
UTL_FILE.FCLOSE_ALL;
END;
Previously I've successfully executed these statements:
create directory sample as 'C:\samples';
(though I can't find the directory on the C:\ drive?)
But this gives me an output like:
ORA-29280: "invalid directory path"
*Cause: A corresponding directory object does not exist.
*Action: Correct the directory object parameter, or create a corresponding directory object with the CREATE DIRECTORY command.
Also I've tried to grant previleges to my username:
grant read, write on directory sample to brick;
But this gives me an output like
ORA-01749: you may not GRANT/REVOKE privileges to/from yourself
What am I doing wrong?
Replace
V_FILEHANDLE := UTL_FILE.FOPEN('C:\samples', '1.csv', 'w');
with :
V_FILEHANDLE := UTL_FILE.FOPEN('SAMPLE', '1.csv', 'w');
As indicated in the doc, the first parameter is the directory object name.
In older versions of Oracle, the first parameter of UTL_FILE.open used to be the directory path, but this has been deprecated since the introduction of the DIRECTORY object (in 9i?).
Thank you SOOO MUCH! I found my error. I was creating the directory like
create or REPLACE DIRECTORY dat_dir as '/u01/oracle/Desktop/Migration/Data';
Then I used it in my UTL_FILE like this
file1 := utl_file.fopen('dat_dir','output.txt','w');
I've been trying this to work for 3 days now. I found the problem, since it's in quotation mark, it's a case sensitive string. It doesn't matter if initially I tiped dat_dir, oracle stores things like this in uppercase. Your simple answer helped me realize this, thank you a million times!
The right way to do it was:
file1 := utl_file.fopen('DAT_DIR','output.txt','w');
I am very new to oracle.I need to create a file with the system timestamp from oracle. Please let me know how do i do that.
More over I need to write any exceptions or errors thrown by my pl/sql code to a file and exit after an error. How do i do this?
Thanks,
Priya.R
It seems you want to look into the UTL_FILE Oracle supplied package, as you're trying to use PL/SQL to create the file.
You can generate the file this way:
(You'll need to create an Oracle DIRECTORY first, pointing to the OS location of the file:
CREATE OR REPLACE DIRECTORY DIR AS 'your OS directory';
Note that the name 'DIR' is used in the sample code that follows. You will also require the CREATE DIRECTORY privilege, and then grant read and write permissions on the directory to the user who will use it:
GRANT READ,WRITE ON DIR TO user1;
)
DECLARE
v_logfile VARCHAR2(100);
v_FH UTL_FILE.FILE_TYPE;
BEGIN
v_logfile := TO_CHAR(SYSDATE,'YYYYMMDD HH24MISS')||'_process.log';
v_FH := UTL_FILE.FOPEN(DIR, v_logfile, 'w');
UTL_FILE.PUTLINE(v_FH, 'Some text on a new line');
UTL_FILE.FCLOSE(v_FH);
END;
This is how you can get a dynamic filename in SQL Plus
SET TERMOUT OFF
DEFINE dynamic_filename = idle
COLUMN which_dynamic NEW_VALUE dynamic_filename
SELECT 'prefix_'
||TO_CHAR( SYSDATE, 'YYYYMMDD' )
||'_'
||TO_CHAR( SYSDATE, 'HH24MISS' )
||'.log' which_dynamic
FROM dual;
SET TERMOUT ON
SPOOL &dynamic_filename
SELECT * FROM dual;
SPOOL OFF
The file gets created in the default directory for SQL Plus (on windows this is the "Start In:" property of the shortcut)
To place the output in a known directory amend the SPOOL command to something like...
SPOOL c:\output_dir\&dynamic_filename
To get an SQL Plus script to exit after an error then include this command...
WHENEVER SQLERROR EXIT SQL.SQLCODE ROLLBACK