how to give relative path of local filesystem in pl/sql block - sql

I am trying to insert a clob from a xml file which is in my local file system. Below is the piece of pl/sql block.
declare
xmlClobFile BFILE := BFILENAME(BFILE_DIR, 'clob.xml');
tempClob CLOB;
begin
EXECUTE IMMEDIATE 'CREATE OR REPLACE DIRECTORY BFILE_DIR AS '||''''||'/home/abc/data/emp/clobs'||''''
--CLOB INSERT
DBMS_LOB.createtemporary(tempClob, TRUE);
DBMS_LOB.open(xmlClobFile, DBMS_LOB.lob_readonly);
DBMS_LOB.loadfromfile(tempClob, xmlClobFile, DBMS_LOB.lobmaxsize);
EXECUTE IMMEDIATE 'insert into emp_data (id, clob_data) values (1000, :1)' using tempClob;
end;
/
Here when I give absolute path (/home/abc/data/emp/clobs) it works. But when I give relative path(like data/emp/clobs) and run this sql from /home/abc, it doesn't work.
[exec] ERROR at line 1:
[exec] ORA-22285: non-existent directory or file for FILEOPEN operation
[exec] ORA-06512: at "SYS.DBMS_LOB", line 937
[exec] ORA-06512: at line 57
How to provide a relative path here, as I want this to be run in any machine and not just mine.

The relative path, if anything will derive from the directory that the Oracle "start" command was run, e.g. /home/oracle. One way to test this, and to verify that relative paths will work (not used them myself) is to create a directory pointing to ".", and run the test to create a file, then search for that file. The directory you find the find in will be your start path. However, I think this is unsafe, since Oracle could be started from any folder (potentially), depending on if its autostarted, or whichever DBA was on hand to start it.

It must be like this one:
xmlClobFile BFILE := BFILENAME('BFILE_DIR', 'clob.xml');

Related

Generate a .log file plsql / oracle

What i want do, is to generate a .log file that describes all my error, start time, end time, and so one. I found a way to have something like that but not in corect way.
I want to generate that file automaticaly, without being required to define it manually.
From what i have understood, is that UTL_FILE.FOPEN, when is not found that file, create one.
My app. is working. The question is, HOW TO GENERATE A FILE IN PLSQL (.log file) without create it manually.
create or replace procedure read_files(input varchar2) as
begin
declare
F2 UTL_FILE.FILE_TYPE;
F2 := UTL_FILE.FOPEN('FOLDER',input||'.log','w');
UTL_FILE.put_line(F2,'Start processing file at : ' || systimestamp);
UTL_FILE.put_line(F2,'End processing file at :'||systimestamp);
-- Close file
UTL_FILE.FCLOSE(F2);
END; --end begin
I found the probleme ! Where I stored my files, I had no right to create files / folders. THANKS all !

Check if Windows batch variable starts with a specific string

How can I find out (with Windows a batch command), if, for example, a variable starts with ABC?
I know that I can search for variables if I know the whole content (if "%variable%"=="abc"), but I want that it only looks after the beginning.
I also need it to find out where the batch file is located, so if there is a other command that reveals the file's location, please let me know.
Use the variable substring syntax:
IF "%variable:~0,3%"=="ABC" [...]
If you need the path to the batch file without the batch file name, you can use the variable:
%~dp0
Syntax for this is explained in the help for the for command, although this variable syntax extends beyond just the for command syntax.
to find batch file location use %0 (gives full patch to current batch file) or %CD% variable which gives local directory

TCL: how to execute program using enviorment PATH variable

I've got following line in my script
exec $::env(PATH)/program.exe
In my env PATH variable I've got a directory where I've got this executable file. For example:
PATH env variable got among other this - D:\my_program\bin
I've got error:
Error:
couldn't execute C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;D:\my_program\bin;\program": no such file or directory
Any suggest how to execute .exe file using system variable like PATH in tcl?
Thanks
PS
OK, when I've create a new env variable (PATH1 - without any other paths, just one) and set .exe file path to it, it seems to work. Any solution to do with PATH (with multiple paths) excluding set D:\my_program\bin in first place?
You should simply use the Tcl library function made for this auto_execok.
Try this:
exec {*}[auto_execok program.exe]
It automatically searches the PATH and constructs the right path for using with exec.
For example, to start notepad.exe:
% auto_execok notepad.exe
C:/windows/system32/notepad.exe
% exec {*}[auto_execok notepad.exe]
To see why the {*} is needed, have a look at http://wiki.tcl.tk/765. Basically auto_execok is pretty smart and can return a list, if needed, e.g. for running start on windows, which needs the expansion to work properly with exec.

PL/SQL TEXT_IO package

I am trying to write to a local file from a PL/SQL script. In order to do this, I am attempting to use the TEXT_IO package in PL/SQL.
DECLARE
file_out text_io.file_type;
len number;
blob_file blob;
my_var RAW(50);
bstart NUMBER := 1;
bytelen NUMBER := 50;
BEGIN
SELECT xxx
INTO blob_file
FROM yyy
WHERE zzz
dbms_lob.read(blob_file, bytelen, bstart, my_var);
file_out := text_io.fopen('local_file_path', 'w');
text_io.put_raw(file_out, my_var);
text_io.fflush(file_out);
text_io.fclose(file_out);
END;
/
quit
However, when I run this script I get the error,
PLS-00201: identifier 'TEXT_IO.FILE_TYPE' must be declared
Does anyone know how I can fix this error, and how I can write the contents of the blob to a file as I am attempting to do?
Thanks,
ktm
TEXT_IO exists only in Oracle Forms which had (in the old client/ server days) a client-side PL/SQL interpreter. If you are using SQL*Plus to execute PL/SQL, as it appears you are doing here, the TEXT_IO package will not be available and you will not be able to write to a file on the client machine (barring the odd setup where the server mounts a drive that your client is exposing and then proceeds to write to that mount).
Now, you can generally use SQL*Plus to directly write to a local file using the SPOOL command. Unfortunately, it's probably unlikely that you could do this for a BLOB in the general case.
If you want to create a file on the server UTL_FILE is a good choice.
This package can write files in any DIRECTORY specified in the database. A DIRECTORY is created in Oracle using CREATE DIRECTORY and can be linked to any writable directory accessible by the DBMS (server-side).
The general approach is: write a file on the server and download it. Or event better, don't write it down, just stream it. Quite complicated, yes.

In Ada, why are my attempts to open a file for writing failing?

When I attempt to open a file to write to I get an Ada.IO_Exceptions.Name_Error.
The file name is "C:\CC_TEST_LOG.TXT". This file does not exist.
This is on Windows XP on an NTFS partition. The user has permissions to create and write to the directory.
The filename is well under the WIN32 max path length.
name_2 : String := "C:\CC_TEST_LOG.TXT"
if name_2'last > name_2'first then
begin
Ada.Text_IO.Create(file, Ada.Text_IO.Out_File, name_2);
Ada.Text_IO.Put_Line(
"CC_Test_Utils: LogFile: ERROR: Open, File "
& name_2);
return;
exception
when The_Error : others =>
Ada.Text_IO.Put_Line(
"CC_Test_Utils: LogFile: ERROR: Open Failed; "
& Ada.Exceptions.Exception_Name(The_Error)
& ", File " & name_2);
end;
end if;
Off the top of my head:
At the time Create is called, file isn't already associated with another open file is it?
What compiler are you using? Gnat is mingw-based, and might not like the windows "C:\" designator. Try taking that part out and see if it creates the file (somewhere).
As Xandy mentioned, the file might already be opened by another program. That Create call requires exclusive access to the file.
As an aside, what is the point of that Put_Line right after the Create? Is successfully opening the file also an error for some reason? It seems like it could perhaps be misleading, making one think the program failed to open the file when it actually succeeded.