I am facing some issue in reading a file using utl_file.
The same code is working fine in some of the instances and failing in one instance.
Below is the issue:
Code:
procedure del_mul_tags(p_request_id in number)
is
fileID UTL_FILE.FILE_TYPE;
fileID1 UTL_FILE.FILE_TYPE;
line varchar2(32000);
l_dir varchar2(1000);
l_file varchar2(20);
l_file1 varchar2(20);
l_request_id number;
l_count number := 0;
l_count_t number :=0;
l_write boolean := TRUE;
cursor c_dir is
select substr(OUTFILE_NAME,1,instr(OUTFILE_NAME,'/',-1,1)-1),substr(OUTFILE_NAME,instr(OUTFILE_NAME,'/',-1,1)+1)
from fnd_concurrent_requests
where request_id = p_request_id;
begin
open c_dir;
fetch c_dir into l_dir,l_file;
close c_dir;
execute immediate 'create or replace directory W2_OUT_DIR as ''' || l_dir || '''';
begin
fileID1 := UTL_FILE.FOPEN ('W2_OUT_DIR', l_file, 'R'); -----Getting the error right here!!!-----------
loop
begin
UTL_FILE.GET_LINE (fileID1, line);
--Some Logic
EXCEPTION WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(fileID1);
EXIT;
end;
end loop;
fileID := UTL_FILE.FOPEN ('W2_OUT_DIR', l_file, 'R');
loop
begin
UTL_FILE.GET_LINE (fileID, line);
--Some Logic
EXCEPTION WHEN NO_DATA_FOUND THEN
UTL_FILE.FCLOSE(fileID);
EXIT;
end;
end loop;
end;
EXCEPTION WHEN OTHERS THEN
fnd_file.put_line(fnd_file.log,'Error while deleting the xml tags: '||SQLERRM);
end;
................
In this instance file, l_file 'ACHAKR01.23067873' was created through another concurrent process. Its OS user is 'appsofde'.
And the unix permissions are as below:
-rw-r--r-- 1 appsofde dba 192092429 jan 27 05:00 ACHAKR01.23067873
The directory W2_OUT_DIR is created and the oracle user apps has EXECUTE,READ,WRITE privileges.
The file exists and the W2_OUT_DIR dir patch is correct.
Exact error coming is:
Error while deleting the xml tags: ORA-29283: invalid file operation
ORA-06512: at "SYS.UTL_FILE", line 536
ORA-29283: invalid file operation
Any thoughts here?
You will want to make sure the filesystem is presented to your Oracle DB host (not just your application server). I'm assuming it is otherwise you would get an invalid directory path error instead. I would suggest you double check however and also ensure the oracle account on the DB host has access to read the file in question. The account appsofde sounds as if its likely the application account.
Related
CREATE OR REPLACE PROCEDURE findSquareRoot
( v_num in NUMBER)
is negative_Number Exception;
BEGIN
if(v_num<0) then
RAISE negative_Number;
else
DBMS_OUTPUT.PUT_LINE ('Square root of '||v_num||' is'||SQRT(v_num));
end if;
EXCEPTION
WHEN negative_Number THEN
RAISE_APPLICATION_ERROR(-20989,'Please provide a valid number');
END;
Test Block using loop
DECLARE
lv_input NUMBER;
BEGIN
LOOP
lv_input := &num
findSquareRoot(lv_input);
EXIT WHEN lv_input > 0;
END LOOP;
end;
Even though I'm mentioning it should exit only when input is greater than zero, Loop is getting executed only once.
in your logic-there is no return value from your procedure findSquareRoot
it is ended up with an exception;
CREATE OR REPLACE PROCEDURE findSquareRoot
( v_num in out NUMBER)
BEGIN
if(v_num<0) then
v_num:=0;
else
v_num:=1;
end if;
EXCEPTION
WHEN others THEN
dbms_outout.put_line(sqlcode);
END;
As you were told, PL/SQL can't help here.
If you're on MS Windows, you might do it with a simple batch script. Here's how.
batch script will ask user to enter a value, and will continue doing that until the positive number is entered
once the above condition is met, it runs SQL*Plus and calls the .SQL script which runs the procedure, passing the parameter user has entered
Here are the scripts:
SQROOT.BAT
#echo off
:repeat
set /p numb="Enter a positive number : "
if %numb% lss 0 goto :repeat
sqlplus scott/tiger#orcl #sqroot %numb%
SQROOT.SQL
set serveroutput on
exec findSquareRoot(&1)
Your procedure
CREATE OR REPLACE PROCEDURE findsquareroot (v_num IN NUMBER)
IS
negative_number EXCEPTION;
BEGIN
IF (v_num < 0)
THEN
RAISE negative_number;
ELSE
DBMS_OUTPUT.put_line (
'Square root of ' || v_num || ' is ' || SQRT (v_num));
END IF;
EXCEPTION
WHEN negative_number
THEN
raise_application_error (-20989, 'Please provide a valid number');
END;
/
Testing:
M:\>sqroot
Enter a positive number : -2
Enter a positive number : 25
SQL*Plus: Release 11.2.0.1.0 Production on Pon Lip 11 08:35:47 2018
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Data Mining and Real Application Testing options
Square root of 25 is 5
PL/SQL procedure successfully completed.
SQL>
This isn't perfect and could/should be improved, but - for a quick note, I hope you got the idea.
I have the following code:
declare
y pls_integer := 0;
v_msg varchar2(4000);
plsql varchar(4000);
begin
if not apex_collection.collection_exists(p_collection_name=>'P16_COLLECTION') then
wwv_flow.debug('No Apex collection found!');
else
for x in (select * from apex_collections where collection_name = 'P16_COLLECTION' and seq_id > 1 order by seq_id)
loop
y := y+1;
FOR i IN 1..25
LOOP
plsql := 'begin apex_collection.update_member_attribute (p_collection_name=> ''P16_COLLECTION'', p_seq=>' || TO_CHAR(x.seq_id) || ',p_attr_number =>' || TO_CHAR(i) || ',p_attr_value=>wwv_flow.g_f' || TO_CHAR(i, 'FM00') || '(' || TO_CHAR(y) || ')); end;';
wwv_flow.debug(plsql);
EXECUTE IMMEDIATE plsql;
END LOOP;
end loop;
end if;
exception when others then
v_msg := ''||sqlerrm;
wwv_flow.debug('ERR: '||v_msg);
end;
This code is very similar to the one proposed here, but I loop through 25 columns. The issue with Oracle Apex is the max number of chars PL/SQL is allowed to have, so I am unable to just write 25 update_member_attribute - calls.
But instead of a it excecuting I get an error no data found.
I triple checked that the collection P16_COLLECTION exists.
The issue with Oracle Apex is the max number of chars PL/SQL is allowed to have
I'm not sure I understood this statement. It is PL/SQL you use. You declared a local PLSQL variable as VARCHAR2(4000). Why didn't you specify its max allowed size, 32767? Would that help?
Furthermore, saying that you got NO-DATA-FOUND exception: are you sure that this piece of code raised it? Because, there's no SELECT statement in there ... the one you used in a cursor FOR loop can't raise NO-DATA-FOUND; UPDATE either. Therefore, it must be something else, I presume.
Enable DEBUG, run the page and - when you get the error - view debug results and locate the culprit.
I have this code to extract Images from an Oracle database using toad but i have challenges when its comes to declare the directory where to save the images once extracted. I want these images to be saved in C:\Images\ a folder in a local machine. Is this possible or how should i specify the directory?.
when i execute the code am getting Invalid file operation
DECLARE
t_blob BLOB;
t_len NUMBER;
t_file_name VARCHAR2(100);
t_output UTL_FILE.file_type;
t_TotalSize number;
t_position number := 1;
t_chucklen NUMBER := 4096;
t_chuck raw(4096);
t_remain number;
BEGIN
-- Get length of blob
SELECT DBMS_LOB.getlength (PHOTO), ename || '_1.jpg'
INTO t_TotalSize, t_file_name FROM DEMO WHERE ENAME ='moon';
t_remain := t_TotalSize;
-- The directory TEMPDIR should exist before executing
t_output := UTL_FILE.fopen ('C:\Images\', t_file_name, 'wb', 32760);
-- Get BLOB
SELECT PHOTO INTO t_blob FROM DEMO WHERE ENAME ='moon';
-- Retrieving BLOB
WHILE t_position < t_TotalSize
LOOP
DBMS_LOB.READ (t_blob, t_chucklen, t_position, t_chuck);
UTL_FILE.put_raw (t_output, t_chuck);
UTL_FILE.fflush (t_output);
t_position := t_position + t_chucklen;
t_remain := t_remain - t_chucklen;
IF t_remain < 4096
THEN
t_chucklen := t_remain;
END IF;
END LOOP;
END;
you should use a DIRECTORY object,
create or replace directory my_dir as 'c:\Images\';
declare
v_dir varchar2(10) := 'MY_DIR';
.....
begin
....
t_output := utl_file.fopen(v_dir, t_file_name, 'wb', 32760);
....
First to know, when you execute any PL/SQL script that handle files this always execute into the scope of the server that run the oracle instance.
In this case the path "C:\Image\" need to exists on the server that Oracle run.
One strategy that you can use is execute the script into the folder of the server and then obtain the folder data via Copy Command on the terminal/console.
I am attempting to encrypt/decrypt a SQLite database via FireDAC in a Delphi XE7 application running on Windows 7 (64 bit).
The code looks like this:
Procedure TMain.ActionBtnClick(Sender: TObject);
Begin
If ActionBtn.Caption = 'Encrypt' Then
Begin
SetPassword;
FDSQLiteSecurity.SetPassword;
End
Else
FDSQLiteSecurity.RemovePassword;
SetStatus;
End;
Procedure TMain.DBNamePropertiesButtonClick(Sender: TObject; AButtonIndex: Integer);
Begin
If OpenDialog.Execute Then
Begin
DBName.Text := OpenDialog.FileName;
SetStatus;
End;
End;
Procedure TMain.FormClose(Sender: TObject; Var Action: TCloseAction);
Var
Reg: TRegistry;
Begin
Reg := TRegistry.Create;
Try
Reg.OpenKey('\SQLiteSecurity', True);
Reg.WriteString('Database', DBName.Text);
Finally
Reg.CloseKey;
Reg.Free;
End;
End;
Procedure TMain.FormShow(Sender: TObject);
Var
Reg: TRegistry;
Begin
DBStatus.Caption := '';
Reg := TRegistry.Create;
Try
Reg.OpenKey('\SQLiteSecurity', True);
If Reg.ValueExists('Database') Then
Begin
DBName.Text := Reg.ReadString('Database');
SetStatus;
End;
Finally
Reg.CloseKey;
Reg.Free;
End;
End;
Procedure TMain.SetPassword;
Var
s: String;
Begin
FDSQLiteSecurity.Database := DBName.Text;
BEK(s);
FDSQLiteSecurity.Password := s;
End;
Procedure TMain.SetStatus;
Begin
DBStatus.Caption := FDSQLiteSecurity.CheckEncryption;
If DBStatus.Caption = '<unencrypted>' Then
ActionBtn.Caption := 'Encrypt'
Else
ActionBtn.Caption := 'Decrypt';
End;
When trying to encrypt, at the line that reads "FDSQLiteSecurity.SetPassword;", I get the following error message:
[FireDAC][Phys][SQLite] ERROR: Cipher: failed to reserve an envelope space.
I have tried to find the meaning of this error message without success. Does anyone know what the error message from SQLite is trying to tell me?
TFDSQLiteSecurityOptions FireDAC.Phys.SQLite.TFDSQLiteSecurity.Options
Have you set option soSetLargeCache ?
Use the Options property to specify the database encryption options.
Due to current SQLite encryption limitation the SetPassword / ChangePassword / RemovePassword calls will fail, if the database has blob fields with a value size greater than 1 DB page, and the database does not fit into the SQLite cache.
If soSetLargeCache is set, then SetPassword / ChangePassword / RemovePassword automatically set the cache size greater than the DB size, to fit the database into the memory in full.
If the DB size is greater than the accessible system memory, then the corresponding call fails.
Am getting this error 'PL/SQL: ORA-00942: table or view does not exist' in Oracle 11G when I try to runt his portion of my script. It seems the select statement isn't parsing the name of the variable from the cursor. Need help to ensure this can read the table name variable from the cursor.
DECLARE
ITEM_ERROR NUMBER;
CNT_SITE VARCHAR2(46);
CURSOR C_SITEID IS
SELECT OBJECTNAME,ATTRIBUTENAME FROM MAXATTRIBUTE WHERE ATTRIBUTENAME LIKE 'SITE%' GROUP BY OBJECTNAME,ATTRIBUTENAME, COLUMNNAME;
SITEIDRec C_SITEID%RowType;
BEGIN
BEGIN
OPEN C_SITEID;
LOOP
FETCH C_SITEID into SITEIDRec;
EXIT WHEN C_SITEID %NOTFOUND;
BEGIN
SELECT COUNT(SITEID) into CNT_SITE FROM SITEIDRec.OBJECTNAME
WHERE SITEID IN ('COLLEGE NANO SCI ENG-TGCM','FREESCALE-BALAZS','TGCM-GLOBAL FOUNDRIES','INTL RECTIFIER-TGM','TGCM-DMOS5','TGCM-IMFT','TGCM-TRIQUINT','GP-TRIQUINT');
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
END LOOP;
--COMMIT;
CLOSE C_SITEID;
--COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
--COMMIT;
EXCEPTION
WHEN OTHERS THEN
MSG_TEXT := SUBSTR(SQLERRM,1,200);
--COMMIT;
raise;
END;
I think you have FROM TableName missing in your query and hence it's rightly complaining.
SELECT COUNT(SITEID) into SITEIDRec.OBJECTNAME
WHERE SITEID IN
('COLLEGE NANO SCI ENG-TGCM','FREESCALE-BALAZS',
'TGCM-GLOBAL FOUNDRIES','INTL RECTIFIER-TGM','TGCM-DMOS5',
'TGCM-IMFT','TGCM-TRIQUINT','GP-TRIQUINT');
Please correct your query by adding the From TableName.
EDIT: Try using EXECUTE IMMEDIATE as below
EXECUTE IMMEDIATE 'SELECT COUNT(SITEID) into CNT_SITE FROM '
|| SITEIDRec.OBJECTNAME ||
' WHERE SITEID IN (''COLLEGE NANO SCI ENG-TGCM'',''FREESCALE-BALAZS'',
''TGCM-GLOBAL FOUNDRIES'',''INTL RECTIFIER-TGM'',''TGCM-DMOS5'',
''TGCM-IMFT'',''TGCM-TRIQUINT'',''GP-TRIQUINT'')';