I have such code:
DECLARE
e_not_exist EXCEPTION;
PRAGMA EXCEPTION_INIT(e_not_exist, -942);
car_name VARCHAR2(20);
BEGIN
select name_of_factory into car_name from car where car_id = 1;
dbms_output.put_line(car_name);
EXCEPTION
when e_not_exist then
dbms_output.put_line('Table or view does not exist');
when OTHERS then
dbms_output.put_line(to_char(SQLCODE));
END;
Actually, my table name is CARS but not CAR. But oracle doesn't handle this exception and gives me an error ORA-00942: Table or view doesn't exist.
How can I handle this exception?
An ORA-00942 error is generally going to be a compile time error. Oracle has to resolve the name(s) of the tables at compile time. Exception handlers will trap errors at runtime, not compile time.
If you used dynamic SQL, you can postpone the resolution of names to runtime at which point you can catch the exception, i.e.
SQL> ed
Wrote file afiedt.buf
1 declare
2 no_such_table exception;
3 pragma exception_init( no_such_table, -942 );
4 l_cnt integer;
5 begin
6 execute immediate 'select count(*) from emps' into l_cnt;
7 exception
8 when no_such_table
9 then
10 dbms_output.put_line( 'No such table' );
11* end;
SQL> /
No such table
PL/SQL procedure successfully completed.
But that is not a sensible way, in general, to write stored procedures. Your procedures should know what tables actually exist and syntax errors should be identified and resolved during development, not at runtime.
You can't do that with static SQL. The error is coming when the code is being compiled, not executed. Try this instead:
execute immediate 'select name_of_factory from car where car_id = 1'
into car_name ;
Related
How can I handle this compilation error through exception?
declare
table_or_view_does_not_exist exception;
pragma exception_init(table_or_view_does_not_exist,-00942);
b exception;
pragma exception_init(b,-00942);
d_table varchar2(200);
c_table varchar2(200);
c_count Number;
begin
begin
d_table:='drop table audit_table PURGE';
execute immediate d_table;
exception
when table_or_view_does_not_exist then
null;
end;
<<lable>>
c_table := 'create table audit_table
(table_name varchar2(50),
column_name varchar2(50),
count_type varchar2(50),
v_count number)';
execute immediate c_table;
select count(*) into c_count from customer_profile where cust_id is null;
insert into audit_table columns (table_name,column_name,count_type,v_count) values('customer_profile','cust_id','null','c_count');
exception
when b then
GOTO lable;
end;
Error report:
ORA-06550: line 25, column 13:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 25, column 1:
PL/SQL: SQL Statement ignored
ORA-06550: line 28, column 2:
PLS-00375: illegal GOTO statement; this GOTO cannot branch to label 'LABLE'
ORA-06550: line 28, column 2:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
What you do, is just bad practice. In Oracle, we don't create tables in PL/SQL but at SQL level and then use them in our procedures.
In your case, you'd
-- create table first
create table audit_table ...;
-- use it in PL/SQL procedure
declare
...
begin
...
insert into audit_table ...
end;
/
You can't "handle" compilation error through exception. What you could do is to put insert statement into dynamic SQL. Also, it wouldn't harm if you used valid syntax (there's no columns "keyword" there).
execute immediate q'[insert into audit_table
(table_name, column_name, count_type, v_count)
values('customer_profile', 'cust_id', 'null', :a)]'
using c_count;
but - once again - that's just bad practice. Don't do it that way, there's no benefit and many disadvantages.
As of goto - well, jumping around your code is almost always wrong. Error you got says that you can't jump out of the exception handler so your idea was wrong anyway.
You actually can trap compilation errors, by wrapping the whole block in an execute immediate so compilation is postponed until runtime. But that's not the right way to go.
Your real issue is that you are referring to the object you are dynamically dropping/creating as a hard-coded dependency of your PL/SQL block:
insert into audit_table ... -- this is a hard dependency
You can't compile PL/SQL if hard dependencies don't exist until run time. If you really must dynamically drop/recreate the table (and I agree with the above reviewer that this is architecturally questionable), you must also make this insert dynamic as well in order to break the dependency chain:
execute immediate 'insert into audit_table values (:col1, :col2, :col3, :col4)' using 'customer_profile','cust_id','null','c_count'; -- this creates no dependency
That will prevent Oracle from creating an object dependency on this table so your code can compile even though the table does not exist at compile time.
But once again, please be sure this is the right technique. There are only a few rare cases where this actually makes good architectural sense. Oh, and please remove the GOTO and label junk. We really don't use that in modern languages; they create unmanageable spaghetti code.
Could you consider another way to control the flow - comments in the code:
DECLARE
cmd VarChar2(200);
c_count Number(6);
--
Status VarChar2(255);
BEGIN
cmd :='drop table audit_table';
Begin -- 1st nested PL/SQL block
Execute Immediate cmd;
Status := 'OK';
Exception -- this could be raised if the table doesn't exist which is probably OK
When OTHERS Then
Status := 'OK'; -- SQLERRM = ORA-00942: table or view does not exist - nothing happens - it would be droped anyway
-- Status := 'ERR - ' || SQLERRM; -- this is alternative if you want to do something else with this ERR
End;
If Status != 'OK' Then -- here you can check the status and decide what to do
GoTo EndIt;
End If;
--
<<lable>> -- in this code there is no need for this label
cmd := 'create table audit_table (table_name varchar2(50), column_name varchar2(50), count_type varchar2(50), v_count number)';
Begin -- 2nd nested PL/SQL block
Execute Immediate cmd;
Status := 'OK';
Exception
When OTHERS Then
Status := 'ERR - ' || SQLERRM;
End;
If Status != 'OK' Then -- here you can check the status and decide what to do
dbms_output.putline(Status); -- send error message and exit - there is no audit_table
GoTo EndIt;
Else
Null; -- here you can do something else (if maybe the table already exists)
End If;
--
-- think about what could go wrong below (2 lines) and either leave it as it is or put it in the 3rd nested PL/SQL block
Select count(*) Into c_count From customer_profile Where cust_id Is Null;
insert into audit_table (table_name, column_name, count_type, v_count) values('customer_profile', 'cust_id', 'Null', c_count);
<<EndIt>> -- used to end the block if needed
Null;
EXCEPTION
When OTHERS Then
dbms_output.putline(SQLERRM); -- You can not get out of here since it is main PL/SQL blok that went into an exception
END;
Addition
Below is an option of basic steps to do the job (3rd block) without compilation errors. I have no possibility to check it out so please do it yourself (there could be some syntax problem or something else). The goal is to be sure that you can insert the record...
I declared sq variable to construct insert command and the end of the code above could be (please check the command yourself - I can't test it right now) something like here:
DECLARE
...
sq VarChar2(1) := ''''; -- this is single-quote character
...
BEGIN
...
...
--
-- think about what could go wrong below (2 lines) and either leave it as it is or put it in the 3rd nested PL/SQL block
Select count(*) Into c_count From customer_profile Where cust_id Is Null;
cmd := 'insert into audit_table (table_name, column_name, count_type, v_count) values(' || sq || 'customer_profile' || sq || ', ' || sq || 'cust_id' || sq || ', ' || sq || 'Null' || sq || ', ' || c_count || ')';
Begin -- 3rd nested PL/SQL block
Select Count(*) Into c_count From all_tables Where table_name = 'audit_table' and owner = 'your_table_owner'; -- check if table exist - if it doesn't set Status
If c_count = 1 Then -- if table exists then you can insert the record
Execute Immediate cmd;
Status := 'OK'; -- all done
Else
Status := 'ERR';
End If;
Exception
When OTHERS Then
Status := 'ERR - ' || SQLERRM; -- catch error and pass it to the main block
End;
If Status != 'OK' Then -- here you can check the status and decide what to do
dbms_output.putline(Status); -- send error message and exit - there is no audit_table -->> OR DO SOMETHING ELSE
GoTo EndIt;
Else
Null; -- here you can do something else if you wish
End If;
--
<<EndIt>> -- used to end the block if needed
Null;
EXCEPTION
When OTHERS Then
dbms_output.putline(SQLERRM); -- You can not get out of here since it is main PL/SQL blok that went into an exception
END;
I'm running the PL/SQL block below from a script. As you can see, it adds a column, and should catch any exceptions - among them, the one that would get thrown in the column already existed.
Now if I run this and the column already exists, I get an error:
Error code: -1735
Error message: ORA-01735: invalid ALTER TABLE option
That is all well and good, but if I run the inner SQL instead though; that is the SQL that follows execute immediate on it's own, I get this message instead, which is more precise:
ORA-01430: column being added already exists in table
The first error has the error code -1735, and I am able to catch with the when-clause that is commented out in the code below; if it is not commented out, the result will instead be:
Some other error occurred
I am not able to catch the -1430 exception though, even though that seems to be the root cause of the exception.
So my question: Is there any way to access this "inner" exception in this case? (is that even a valid term in this case?) In other words, can this be modified so as to provide a more specific error message?
DECLARE
column_exists exception;
pragma exception_init (column_exists , -1430);
general_error exception;
pragma exception_init (general_error , -1735);
BEGIN
execute immediate 'ALTER TABLE my_table
ADD (some_column VARCHAR2(10 CHAR));';
EXCEPTION
-- I expected / wanted this to catch my error in order
-- to let me output a more specific message:
WHEN column_exists THEN
DBMS_OUTPUT.PUT_LINE('The column or index already exists');
-- Note: Commented out, but would otherwise catch the general error.
-- (I tested it here just to confirm that I can catch exceptions this way)
-- WHEN general_error THEN
-- DBMS_OUTPUT.PUT_LINE('Some other error occurred');
-- General catch: Generates the first message quoted above:
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error code: ' || SQLCODE);
DBMS_OUTPUT.PUT_LINE('Error message: ' || SQLERRM);
END;
/
This is what I get after modifying your code a little bit:
In line #9, there's a semi-colon which should be removed as EXECUTE IMMEDIATE doesn't allow it, here:
ADD (some_column VARCHAR2(10 CHAR));';
^
|
remove it
Sample table:
SQL> CREATE TABLE test
2 AS
3 SELECT * FROM dept;
Table created.
Your code:
SQL> DECLARE
2 column_exists EXCEPTION;
3 PRAGMA EXCEPTION_INIT (column_exists, -1430);
4
5 general_error EXCEPTION;
6 PRAGMA EXCEPTION_INIT (general_error, -1735);
7 BEGIN
8 EXECUTE IMMEDIATE 'ALTER TABLE test
9 ADD (loc VARCHAR2(10 CHAR))'; --> remove ; here
10 EXCEPTION
11 -- I expected / wanted this to catch my error in order
12 -- to let me output a more specific message:
13 WHEN column_exists
14 THEN
15 DBMS_OUTPUT.PUT_LINE ('The column or index already exists');
16 -- Note: Commented out, but would otherwise catch the general error.
17 -- (I tested it here just to confirm that I can catch exceptions this way)
18 -- WHEN general_error THEN
19 -- DBMS_OUTPUT.PUT_LINE('Some other error occurred');
20
21 -- General catch: Generates the first message quoted above:
22 WHEN OTHERS
23 THEN
24 DBMS_OUTPUT.PUT_LINE ('Error code: ' || SQLCODE);
25 DBMS_OUTPUT.PUT_LINE ('Error message: ' || SQLERRM);
26 END;
27 /
The column or index already exists
PL/SQL procedure successfully completed.
SQL>
Now, I'm not sure whether it was the case with the superfluous semi-colon or not. Remove it and rephrase the question, if necessary.
This question already has answers here:
Oracle: If Table Exists
(16 answers)
Closed 6 years ago.
I am using Oracle 12c and I am not interesting to have an error while droping my table 'CONTINENT' in case it doesn't exist.
I did this
set echo on
set serveroutput on
alter session set current_schema=WORK_ODI;
set verify off
set pause off
begin
execute immediate 'drop table continent';
exception when others then null;
end;
This script is work with me well. and I use this script too :
declare
c int;
begin
select count(*) into c from user_tables where table_name = upper('continent');
if c = 1 then
execute immediate 'drop table continent';
end if;
end;
the both scripts work well but my boss wants something like IF EXIT. Anybody can help me please. how to use IF EXIT in this case ?
Sorry, there is no if exists in the Oracle's drop table syntax.
You can do two things
define the exception you want to ignore (here ORA-00942)
add an undocumented (and not implemented) hint /*+ IF EXISTS */ that will pleased you management.
.
declare
table_does_not_exist exception;
PRAGMA EXCEPTION_INIT(table_does_not_exist, -942);
begin
execute immediate 'drop table continent /*+ IF EXISTS */';
exception when table_does_not_exist then
DBMS_OUTPUT.PUT_LINE('Ignoring table or view does not exist')
;
end;
/
Additional note: the usage of
exception when others then null;
may be dangerous, as for example you ignore also errors such as tablespace offline, when the table is NOT DROPPED.
set echo on
set serveroutput on
alter session set current_schema=WORK_ODI;
set verify off
set pause off
WHENEVER OSERROR EXIT FAILURE ROLLBACK
drop table continent;
WHENEVER OSERROR CONTINUE
I had a similar problem - i needed a way how to repeat DDL scripts without modifying them. Imaging the following script:
create table tab1(...);
create table tab2(...);
create table tab3{...}; /* <--- this one fails*/
create table tab4(...);
so now we have the following situation: tables "tab1" and "tab2" have been successfully created, "tab3" and "tab4" are missing.
So after fixing statement for the "tab3" table we would have to comment out create statements for "tab1" and "tab2" - it might be very annoying when working with big SQL scripts containing many DDLs and many bugs.
So i came up with the following procedure which allows to re-run DDL statements:
create or replace procedure re_run_ddl (p_sql in varchar2)
AUTHID CURRENT_USER
as
l_line varchar2(500) default rpad('-',20,'-');
l_cr varchar2(2) default chr(10);
l_footer varchar2(500) default l_cr||rpad('*',20,'*');
l_ignore_txt varchar2(200) default 'IGNORING --> ';
ORA_00955 EXCEPTION;
ORA_01430 EXCEPTION;
ORA_02260 EXCEPTION;
ORA_01408 EXCEPTION;
ORA_00942 EXCEPTION;
ORA_02275 EXCEPTION;
ORA_01418 EXCEPTION;
ORA_02443 EXCEPTION;
ORA_01442 EXCEPTION;
ORA_01434 EXCEPTION;
ORA_01543 EXCEPTION;
ORA_00904 EXCEPTION;
ORA_02261 EXCEPTION;
ORA_04043 EXCEPTION;
ORA_02289 EXCEPTION;
PRAGMA EXCEPTION_INIT(ORA_00955, -00955); --ORA-00955: name is already used by an existing object
PRAGMA EXCEPTION_INIT(ORA_01430, -01430); --ORA-01430: column being added already exists in table
PRAGMA EXCEPTION_INIT(ORA_02260, -02260); --ORA-02260: table can have only one primary key
PRAGMA EXCEPTION_INIT(ORA_01408, -01408); --ORA-01408: such column list already indexed
PRAGMA EXCEPTION_INIT(ORA_00942, -00942); --ORA-00942: table or view does not exist
PRAGMA EXCEPTION_INIT(ORA_02275, -02275); --ORA-02275: such a referential constraint already exists in the table
PRAGMA EXCEPTION_INIT(ORA_01418, -01418); --ORA-01418: specified index does not exist
PRAGMA EXCEPTION_INIT(ORA_02443, -02443); --ORA-02443: Cannot drop constraint - nonexistent constraint
PRAGMA EXCEPTION_INIT(ORA_01442, -01442); --ORA-01442: column to be modified to NOT NULL is already NOT NULL
PRAGMA EXCEPTION_INIT(ORA_01434, -01434); --ORA-01434: private synonym to be dropped does not exist
PRAGMA EXCEPTION_INIT(ORA_01543, -01543); --ORA-01543: tablespace '<TBS_NAME>' already exists
PRAGMA EXCEPTION_INIT(ORA_00904, -00904); --ORA-00904: "%s: invalid identifier"
PRAGMA EXCEPTION_INIT(ORA_02261, -02261); --ORA-02261: "such unique or primary key already exists in the table"
PRAGMA EXCEPTION_INIT(ORA_04043, -04043); --ORA-04043: object %s does not exist
PRAGMA EXCEPTION_INIT(ORA_02289, -02289); --ORA-02289: sequence does not exist
procedure p(
p_str in varchar2
,p_maxlength in int default 120
)
is
i int := 1;
begin
dbms_output.enable( NULL );
while ( (length(substr(p_str,i,p_maxlength))) = p_maxlength ) loop
dbms_output.put_line(substr(p_str,i,p_maxlength));
i := i + p_maxlength;
end loop;
dbms_output.put_line(substr(p_str,i,p_maxlength));
end p;
begin
p( 'EXEC:'||l_cr||l_line||l_cr||p_sql||l_cr||l_line );
execute immediate p_sql;
p( 'done.' );
exception
when ORA_00955 or ORA_01430 or ORA_02260 or ORA_01408 or ORA_00942
or ORA_02275 or ORA_01418 or ORA_02443 or ORA_01442 or ORA_01434
or ORA_01543 or ORA_00904 or ORA_02261 or ORA_04043 or ORA_02289
then p( l_ignore_txt || SQLERRM || l_footer );
when OTHERS then
p( SQLERRM );
p( DBMS_UTILITY.FORMAT_ERROR_BACKTRACE );
p( l_footer );
RAISE;
end;
/
show err
Usage example:
set serveroutput on
begin
re_run_ddl('
create table test
(
id number,
s varchar2(30)
)
');
end;
/
exec re_run_ddl('drop table test');
exec re_run_ddl('drop table test');
exec re_run_ddl('drop table test');
Output:
EXEC:
--------------------
create table test
(
id number,
s varchar2(30)
)
--------------------
done.
PL/SQL procedure successfully completed.
EXEC:
--------------------
drop table test
--------------------
done.
PL/SQL procedure successfully completed.
stx11de2> EXEC:
--------------------
drop table test
--------------------
IGNORING --> ORA-00942: table or view does not exist
********************
PL/SQL procedure successfully completed.
stx11de2> EXEC:
--------------------
drop table test
--------------------
IGNORING --> ORA-00942: table or view does not exist
********************
PL/SQL procedure successfully completed.
I have a PL/SQL script to perform some aggregation tasks. I am having compilation errors, logic is not top priority at this moment as that can be changed once the errors are resolved. The script is as follows :
SET SERVEROUTPUT ON;
ALTER SESSION SET NLS_DATE_FORMAT = 'dd-MON-yy';
CREATE OR REPLACE PROCEDURE updateFeaturePerformanceTable
(noOfDays IN NUMBER, runDate IN DATE, timeSpan IN VARCHAR2)
AS
CURSOR c_feature_performance IS
SELECT distinct mkt_id,dow,device_type,feature_name
FROM gfmdev.feature_performance
WHERE timespan = 'ONE_DAY'
AND feature_performance_day >= TO_DATE('17-AUG-15','dd-MON-yy');
rowsExtracted c_feature_performance%ROWTYPE;
extractDate DATE;
timespan_test varchar2(20);
BEGIN
OPEN c_feature_performance;
extractDate := runDate - noOfDays;
timespan_test := timeSpan;
LOOP
FETCH c_feature_performance INTO rowsExtracted;
EXIT WHEN c_feature_performance%NOTFOUND;
dbms_output.put_line(extractDate || ' ' || timespan_test);
INSERT INTO gfmdev.feature_performance
SELECT
rowsExtracted.mkt_id,
rowsExtracted.dow,
rowsExtracted.device_type,
rowsExtracted.feature_name,
SUM(OPS),
SUM(GV_COUNT),
runDate,
timespan_test
FROM gfmdev.feature_performance
WHERE feature_performance_day BETWEEN extractDate AND runDate
AND timespan = 'ONE_DAY'
AND mkt_id = rowsExtracted.mkt_id
AND dow = rowsExtracted.dow
AND device_type = rowsExtracted.device_type
AND feature_name = rowsExtracted.feature_name
group by mkt_id, dow, device_type, feature_name, timespan;
END LOOP;
CLOSE c_feature_performance;
EXCEPTION
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Trying to insert too many rows in SELECT...INTO');
ROLLBACK;
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No rows returned in SELECT...INTO');
ROLLBACK;
WHEN STORAGE_ERROR THEN
dbms_output.put_line('Too much data to handle! Storage error');
ROLLBACK;
WHEN OTHERS THEN
dbms_output.put_line('Oops! Something went wrong');
ROLLBACK;
RAISE;
END updateFeaturePerformanceTable;
Show compilation errors:
SHOW ERRORS PROCEDURE updateFeaturePerformanceTable;
Run the procedure:
DECLARE
runDate DATE;
BEGIN
FOR j IN 0 .. 5 LOOP
SELECT (TO_DATE('17-AUG-15','dd-MON-yy') + j) INTO runDate FROM dual;
updateFeaturePerformanceTable(6,runDate, 'ONE_WEEK');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' WEEKLY RECORDS UPDATED ');
FOR j IN 0 .. 28 LOOP
SELECT (TO_DATE('17-AUG-15','dd-MON-yy') + j) INTO runDate FROM dual;
updateFeaturePerformanceTable(29,runDate, 'ONE_MONTH');
END LOOP;
DBMS_OUTPUT.PUT_LINE(' MONTHLY RECORDS UPDATED ');
COMMIT;
END;
/
When I execute it I get the following error message :
Errors for PROCEDURE UPDATEFEATUREPERFORMANCETABLE:
LINE/COL ERROR
-------- -----------------------------------------------------------------
4/9 PLS-00341: declaration of cursor 'C_FEATURE_PERFORMANCE' is
incomplete or malformed
5/3 PL/SQL: SQL Statement ignored
6/15 PL/SQL: ORA-00942: table or view does not exist
8/16 PL/SQL: Item ignored
16/3 PL/SQL: SQL Statement ignored
16/36 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
21/3 PL/SQL: SQL Statement ignored
LINE/COL ERROR
-------- -----------------------------------------------------------------
36/22 PL/SQL: ORA-00904: "ROWSEXTRACTED"."FEATURE_NAME": invalid
identifier
36/22 PLS-00320: the declaration of the type of this expression is
incomplete or malformed
updateFeaturePerformanceTable(6,runDate, 'ONE_WEEK');
*
Any help on where I am going wrong is highly appreciated?
PL/SQL is a framework for running SQL statements programmatically. So often we find that PL/SQL errors are caused by the SQL errors in our code.
That is the case here. You have several PL/SQL errors indicating that the Cursor declaration is invalid. And why is it invalid? This line holds the answer:
6/15 PL/SQL: ORA-00942: table or view does not exist
So the problem is, the owner of the procedure UPDATEFEATUREPERFORMANCETABLE (ugly name by the way) does not have rights on gfmdev.feature_performance.
To solve, the table owner GFMDEV needs to grant SELECT and INSERT directly to the account which owns this procedure.
SQL> conn gfmdev/password
SQL> grant select, insert on feature_performance to whoever;
Note that granting privileges through a view won't cut it. The Oracle security model only permits us to build objects - PL/SQL programs, views - with privileges granted directly to our user.
I'm trying to develop a procedure which will read a BLOB field of a table and write an RTF document which will be used as template to another procedure but when the procedure fires up the select statemente, i got stuck with a ORA-06502 error.
This error, after reading the documentation, is caused by incompatibilities between fields (numeric or value error string)
But i've seen this example everywhere in the internet and i'm running out of ideas of what is causing it.
The source code of my procedure follows:
PROCEDURE p_transfer_db_client(pcPath IN VARCHAR2,
pnSequence IN NUMBER) IS
v_src_blob BLOB;
v_file UTL_FILE.FILE_TYPE;
v_offset INTEGER := 1;
v_amount BINARY_INTEGER := 32766;
v_binary_buffer RAW(32767);
BEGIN
SELECT model
INTO v_src_blob
FROM models
wHERE id = pnSequence;
v_file := UTL_FILE.FOPEN(pcPath, 'model.rtf', 'wb', v_amount);
LOOP
BEGIN
DBMS_LOB.READ(v_src_blob, v_amount, v_offset, v_binary_buffer);
UTL_FILE.PUT_RAW(v_file, v_binary_buffer);
v_offset := v_offset + v_amount;
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
UTL_FILE.FFLUSH(v_file);
UTL_FILE.FCLOSE(v_file);
END p_transfer_db_client;
Edit: I hadn't seen that you had tagged this question as forms.
Your code won't work inside forms: UTL_FILE and DBMS_LOB run on the DB server, not the forms client so they should be in a PL/SQL procedure, not a Forms procedure.
I'm pretty sure the BLOB datatype is not managed like this in forms, in fact I'm surprised it even compiles!
Take a look at this example showing how to handle blobs inside forms for instance, and you will see that you need to define and query the blob inside a PLSQL procedure, not directly through forms.
I suggest you create the procedure inside the DB as a PLSQL package and call this package from your forms client.
There is something else going on, I can't see why the SELECT statement wouldn't work.
Do you still get the error if you comment out all variables declarations and all the following statements, i.e:
SQL> create table models (
2 inst_num_instituicao NUMBER(2) not null,
3 id NUMBER(3) not null,
4 model BLOB not null);
Table created.
SQL> insert into models values (1, 1, hextoraw('FFFF'));
1 row created.
SQL> declare
2 b blob;
3 begin
4 select model into b from models where id = 1;
5 end;
6 /
PL/SQL procedure successfully completed.