Can't write to a file. Oracle - oracle

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');

Related

How can this code generate a file with a filename containing a colon on Windows?

I see the pascal code below on another forum. How can this code be possible?
Doesn't windows allow user to create a filename with colon?
However, this code only work when you create a file with name contains colon in root directory of drive (Ex: D:, C:, E:, etc). And when the file is created, it's completely invisible.
uses crt, sysutils;
var
f, f1: file of char;
c:char;
begin
clrscr;
assign(f, 'D:\src\payload.exe');
reset(f);
assign(f1, 'D:\:malware.exe');
rewrite(f1);
while not eof(f) do
begin
read(f, c);
write(f1, c);
end;
close(f1);
close(f);
executeprocess('D:\:malware.exe', ''); //here
readln;
erase(f1);
end.
You can compile the code above with free pascal
fpc [filename].pas
Thank you.
EDIT:
For more detail:
You can execute D:\:malware.exe from CreateProcess (WinAPI)
You can't execute D:\:malware.exe from command line, path, etc
I use process explorer to find D:\:malware.exe path/contain folder. However, when I pressed explore button, it takes me to %UserProfile%
It only work for D:\:malware.exe, D:\\malware.exe, D:\/malware.exe
It works because it is possible*. You can name files all kinds of horrid things, regardless of proper naming convention.
*Yes, I know MSDN lists colons as “reserved”. That is not the same as forbidden or impossible. It is only the same as “don’t do it”.

how to create directory in oracle home

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';

How to access user directory in lazarus?

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.

How to move a text file using Oracle

I have two questions.
(1) how to make move text file from folder:
C:\Data\inbox\test.txt
to target Folder?
C:\Data\outbox\test.txt
(2) how to make get list of directory files in Folder?
C:\Data\inbox\
Thank you...
Oracle provides a package of utilities for working with files, UTL_FILE. Since 9i this has included the FRENAME() procedure, which works like the unix mv command. We can use it to rename the file and/or its directory. Note that the Oracle os account must have read and write privileges on both directories. Also this procedure uses DIRECTORY objects, rather than explicit paths.
As for getting a list of files in a directory, there is no Oracle built-in. One solution is to use a Java Stored Procedure. Tom Kyte has an example of this. Find it here. There is another way of doing it since 11.1.0.7, which is to use an external table pre-processor file. Adrian Billington wrote a nice article on this. The executed file is platform dependent.
Have a look at UTL_FILE?
http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/u_file.htm
Where you say:
2-) Question Two
Folder: C:\Data\inbox\
how to make get directory files list ?
Tom Kyte has a nice solution shown here
begin
UTL_FILE.FCOPY (
'EMPLOYEE' , -- THIS IS A ORACLE DIRECTORY
'EmpInfo.TXT' , --FILE NAME
'PROM_INCR' , -- THIS IS A ORACLE DIRECTORY
'EmpInfo.TXT' ); -- DESTINATION FILE
end;
try this

How to append system time to the file name in oracle?

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

Resources