FRM-40735: When button pressed trigger raised unhandled exception ORA-06502 - sql

if :entete.carto = 'O' then
declare
c_criteres varchar2(240);
BEGIN
go_item(:ENTETE.CURRENT_ITEM_PRECEDENT);
IF :ENTETE.LOX_BE='PTV' THEN
:global.type_lancement := 'GEOCOD';
c_criteres := '-jar '|| :entete.empl_jar||'geocodeur.jar '
|| :entete.c_user || ' '
|| :entete.c_passe || ' '
|| :global.connection_string || ' '
|| '1 ' -- ecrire dans un fichier en sortie
|| '1 ' -- debug
|| '1' /*geocod cf*/ || ' '
|| :global.chemin_cr || ' '
|| :global.utilisateur;
lancer_executable('javaw',:entete.c_user,:entete.c_passe,
:entete.c_noeud,:entete.c_os,'1',c_criteres);
END IF;
enter_query;
END;
end if;
can someone advise about the reason for such an error?
I am new to oracle forms and need to figure out why this issue is occuring in order to resolve it.
thank you

Usually this error is because you are trying to assign a value to a variable or field that is not to big enough. Example
v_name VARCHAR2(5);
After you try to:
v_name := 'ABCDEFGHIJK';
The variable's length is 5 and you try to assign a string with 10 characters.
Hope it helps.

Related

Convert dbms_output to html and selectively suppress other output

I am using the code below which outputs as intended:
DECLARE
v_ins_param VARCHAR2(10);
CURSOR c_ins_param IS
SELECT status
FROM v$instance;
BEGIN
OPEN c_ins_param;
LOOP
FETCH c_ins_param INTO v_ins_param;
EXIT WHEN c_ins_param%NOTFOUND;
--
--
--
IF v_ins_param = 'OPEN' THEN
DBMS_OUTPUT.PUT_LINE('
' || CHR(35) || '' || CHR(35) ||'' || CHR(35) || '
Great! Your database is up.
' || CHR(35) || '' || CHR(35) ||'' || CHR(35) || ' ');
ELSIF v_ins_param = 'MOUNTED' THEN
DBMS_OUTPUT.PUT_LINE('
' || CHR(35) || '' || CHR(35) ||'' || CHR(35) || '
Database is only mounted.
' || CHR(35) || '' || CHR(35) ||'' || CHR(35) || '
');
ELSE
DBMS_OUTPUT.PUT_LINE('
' || CHR(35) || '' || CHR(35) ||'' || CHR(35) || '
Database is neither mounted or open.
' || CHR(35) || '' || CHR(35) ||'' || CHR(35) || '
');
END IF;
END LOOP;
CLOSE c_ins_param;
END;
/
This is the "kind" of output it'll give you:
###
Great! Your database is up.
###
Ultimately this will be a series of anonymous block "typed" scripts like this one which I want to output to a single file.
I am now trying to get the output to just give the text information only, in a html output. I saw this on another page and adapted it for my code to see how it would / could work:
spool c:mag.html
DECLARE
CURSOR c1 IS
SELECT * FROM dept;
BEGIN
DBMS_OUTPUT.PUT_LINE('< pre >');
DBMS_OUTPUT.PUT_LINE('< h1 >Report on Databases</h1>');
FOR mag IN c1
LOOP
EXIT WHEN c1%notfound;
DBMS_OUTPUT.PUT_LINE('< b >Department Name[/b] =' || mag.dname);
END LOOP;
END;
/
However the way of doing this, using:
mag.dname
is not applicable in my 'non for loop' example.
I feel like there must be a more appropriate way of achieving the output. I have tried:
set markup html on
And it does not just returned impact the output but ALL of the code.
Has anyone tried this before and know perhaps how I might get the html output for the returned data only?
Here's an example - I store the following in a script called (say) scr.sql
set termout off
set feedback off
set serverout on
begin
for i in (
select
case
when status = 'OPEN' then '<p>Database is open</p>'
when status = 'MOUNTED' then '<p>Database is mounted</p>'
else '<p>Database is not happy</p>'
end status_output
from v$instance
)
loop
dbms_output.put_line(i.status_output);
end loop;
end;
.
spool /tmp/status.html
/
spool off
and then run this from SQLPlus as
SQL> #scr.sql
and the only thing my resultant status.html is
<p>Database is open</p>

Problem with PL/SQL anonymous block in an exam

I am working with a code in SQLDeveloper for an exam and I'm having problems with the code. The error shown is
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 7
00000 - "PL/SQL: numeric or value error%s"
*Cause: An arithmetic, numeric, string, conversion, or constraint error
occurred. For example, this error occurs if an attempt is made to
assign the value NULL to a variable declared NOT NULL, or if an
attempt is made to assign an integer larger than 99 to a variable
declared NUMBER(2).
*Action: Change the data, how it is manipulated, or how it is declared so
that values do not violate constraints.
The code I'm using is this one:
VAR RUT_CLIENTE VARCHAR2(15);
EXEC :RUT_CLIENTE:= '12487147-9';
DECLARE
V_NOMBRE VARCHAR2(75);
V_RUN VARCHAR2(50);
V_RENTA VARCHAR2(12);
V_EST_CIVIL VARCHAR2(40);
BEGIN
SELECT
CLI.NOMBRE_CLI || ' ' || CLI.APPATERNO_CLI || ' ' || CLI.APMATERNO_CLI,
TO_CHAR(CLI.NUMRUT_CLI || '-' || CLI.DVRUT_CLI),
TO_CHAR(CLI.RENTA_CLI, '$999G999G999'),
EST.DESC_ESTCIVIL
INTO V_NOMBRE, V_RUN, V_RENTA, V_EST_CIVIL
FROM CLIENTE CLI JOIN ESTADO_CIVIL EST
ON CLI.ID_ESTCIVIL = EST.ID_ESTCIVIL
WHERE CLI.NUMRUT_CLI || '-' || CLI.DVRUT_CLI = :RUT_CLIENTE;
DBMS_OUTPUT.PUT_LINE('DATOS DEL CLIENTE');
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('----------------');
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('Nombre: ' || V_NOMBRE);
DBMS_OUTPUT.PUT_LINE('RUN: ' || V_RUN);
DBMS_OUTPUT.PUT_LINE('Estado Civil: ' || V_EST_CIVIL);
DBMS_OUTPUT.PUT_LINE('Renta: ' || V_RENTA);
END;
What am I doing wrong? Also, I have to make this block run three times, each time having to enter a different RUT_CLIENTE (the equivalent of the Social Security number in Chile) to show different results, so should I use a loop for that?
You can avoid such errors if you will use define your variables using the types from your cursor:
DECLARE
cursor cur(p_RUT_CLIENTE) is
SELECT
CLI.NOMBRE_CLI || ' ' || CLI.APPATERNO_CLI || ' ' || CLI.APMATERNO_CLI as col_nombre,
TO_CHAR(CLI.NUMRUT_CLI || '-' || CLI.DVRUT_CLI) as col_run,
TO_CHAR(CLI.RENTA_CLI, '$999G999G999') as col_renta,
EST.DESC_ESTCIVIL as col_est_civil
FROM CLIENTE CLI JOIN ESTADO_CIVIL EST
ON CLI.ID_ESTCIVIL = EST.ID_ESTCIVIL
WHERE CLI.NUMRUT_CLI || '-' || CLI.DVRUT_CLI = p_RUT_CLIENTE;
V_NOMBRE cur.col_nombre%type;
V_RUN cur.col_run%type;
V_RENTA cur.col_renta%type;
V_EST_CIVIL cur.est_civil%type;
BEGIN
open cur(:RUT_CLIENTE)
fetch cur into INTO V_NOMBRE, V_RUN, V_RENTA, V_EST_CIVIL;
close cur;
DBMS_OUTPUT.PUT_LINE('DATOS DEL CLIENTE');
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('----------------');
DBMS_OUTPUT.PUT_LINE(' ');
DBMS_OUTPUT.PUT_LINE('Nombre: ' || V_NOMBRE);
DBMS_OUTPUT.PUT_LINE('RUN: ' || V_RUN);
DBMS_OUTPUT.PUT_LINE('Estado Civil: ' || V_EST_CIVIL);
DBMS_OUTPUT.PUT_LINE('Renta: ' || V_RENTA);
END;

continuing loops a thing in oracle

I am carrying out another exercise to learn various things about Oracle SQL's syntax today's lesson I've chosen are loops. Please see below code where I am trying to have two fields (temp variables) having values being decreased until it's less than zero depending on which of the variables hit's zero depends on what text I would like to output into the script output. Hopefully it makes sense. If I have made any faux pas's please do shout at me.
DECLARE
"Character" VARCHAR2(255);
"Enemy" VARCHAR2(255);
"Character_Health" NUMBER;
"Enemy_Health" NUMBER;
"Character_Attack" NUMBER;
"Enemy_Attack" NUMBER;
BEGIN -- Generates Base Stats
SELECT 'Hero' INTO "Character" FROM dual;
SELECT 'Villain' INTO "Enemy" FROM dual;
SELECT 100 INTO "Character_Health" FROM dual;
SELECT 25 INTO "Enemy_Health" FROM dual;
SELECT 10 INTO "Character_Attack" FROM dual;
SELECT 5 INTO "Enemy_Attack" FROM dual;
dbms_output.put_line ("Character" || ' (' || "Character_Health" || ') VS ' ||' '|| "Enemy" || ' (' || "Enemy_Health" || ')') ;
dbms_output.put_line ('');
dbms_output.put_line ('FIGHT!');
BEGIN -- Round 1
LOOP
dbms_output.put_line ('');
SELECT "Enemy_Health" - "Character_Attack" INTO "Enemy_Health" FROM dual; -- Hero hits Villain
dbms_output.put_line ("Character" || ' Hits ' || "Enemy" || ' for ' || "Character_Attack" ||' Damage' );
dbms_output.put_line ("Enemy" || ' Has ' || "Enemy_Health" || ' Health Remaining ');
CASE WHEN "Enemy_Health" < 0 THEN dbms_output.put_line ("Enemy" || 'Has Fainted' || "Character" || 'Wins!');
ELSE CONTINUE;
EXIT WHEN "Enemy_Health" < 0;
SELECT "Character_Health" - "Enemy_Attack" INTO "Character_Health" FROM dual; -- Villain hits Hero
dbms_output.put_line ('');
dbms_output.put_line ("Enemy" || ' Hits ' || "Character" || ' for ' || "Enemy_Attack" ||' Damage' );
dbms_output.put_line ("Character" || ' Has ' || "Character_Health" || ' Health Remaining ');
CASE WHEN "Character_Health" < 0 THEN dbms_output.put_line ("Character" || 'Has Fainted' || "Enemy" || 'Wins!');
ELSE CONTINUE;
EXIT WHEN "Character_Health" < 0;
END LOOP;
END;
END;
I found some errors
1. Syntax for case is:
CASE [ expression ]
WHEN condition_1 THEN result_1
WHEN condition_2 THEN result_2
...
WHEN condition_n THEN result_n
[ELSE result]
END CASE
Learn more:
- simple case statement
- searched case statement
CONTINUE stops processing loop and starts it from the begining, so your logic is corrupt - only Hero is attacking.
You need space after "Fainted"
It's better to use IF in this case:
IF "Character_Health" < 0
THEN
dbms_output.put_line ("Character" || 'Has Fainted. ' || "Enemy" || 'Wins!');
EXIT;
END IF;
It's not mistake, but you don't need select into from dual if you want to change value of variable.
Last but not least- i don't like how you use variables. "Character_Health" is similar to 'Character_Health' or '''Character_Health'''. Better use names like characterHealth or character_health.
My version would be something like that:
DECLARE
v_Character VARCHAR2(255) := 'Hero' ;
v_Enemy VARCHAR2(255) := 'Villain';
v_Character_Health NUMBER := 100;
v_Enemy_Health NUMBER := 25;
v_Character_Attack NUMBER := 10;
v_Enemy_Attack NUMBER := 5;
v_nl VARCHAR2(1) := chr(10);
BEGIN
dbms_output.put_line (v_Character || ' (' || v_Character_Health || ') VS ' ||' '|| v_Enemy || ' (' || v_Enemy_Health || ')' || v_nl) ;
dbms_output.put_line ('FIGHT!' || v_nl);
LOOP
v_Enemy_Health := v_Enemy_Health - v_Character_Attack;
dbms_output.put_line (v_Character || ' Hits ' || v_Enemy || ' for ' || v_Character_Attack ||' Damage' );
dbms_output.put_line (v_Enemy || ' Has ' || v_Enemy_Health || ' Health Remaining' || v_nl);
IF v_Enemy_Health < 0 THEN dbms_output.put_line (v_Enemy || 'Has Fainted. ' || v_Character || 'Wins!'); EXIT;
END IF;
v_Character_Health := v_Character_Health - v_Enemy_Attack;
dbms_output.put_line (v_Enemy || ' Hits ' || v_Character || ' for ' || v_Enemy_Attack || ' Damage' );
dbms_output.put_line (v_Character || ' Has ' || v_Character_Health || ' Health Remaining' || v_nl);
IF v_Character_Health < 0 THEN dbms_output.put_line (v_Character || 'Has Fainted. ' || v_Enemy || 'Wins!'); EXIT;
END IF;
END LOOP;
END;
/

Reading rows from an Oracle Object that is a table of other objects

Forgive me, this is my first attempt at an Oracle Package, so I am hopefully missing something simple.
EDIT I sorted it...
Need to reference the actual declaring sub-type, as such:
FOR j in outvar(i).tbl_ORDER_TENDERS.first..outvar(i).tbl_ORDER_TENDERS.last LOOP
DBMS_OUTPUT.PUT_LINE('tender record : '
|| to_char(outvar(i).tbl_ORDER_TENDERS(j).TENDER_AMT) || ' '
I created several a couple new Oracle Types, that will hold row data from my DB, as such:
create or replace
TYPE ORDERS_TABLE
IS TABLE OF ORDER_HEADER;
And that refers to my other type:
create or replace
TYPE ORDER_HEADER FORCE
AS OBJECT (
TRANSACTION_NUMBER VARCHAR2(20),
LOCATION_NUMBER VARCHAR2(10),
TERMINAL_NAME VARCHAR2(25),
START_DATETIME TIMESTAMP(6),
GROSS_SALES_AMOUNT NUMBER(20,0),
NET_SALES_AMOUNT NUMBER(20,0),
SAVINGS_AMOUNT NUMBER(20,0),
SAVINGS_PRECISION NUMBER(6,0),
TOTAL_TAX NUMBER(20,0),
CUSTOMER_IDENTIFIER VARCHAR2(50),
tbl_ORDER_LINES ORDER_LINES,
tbl_ORDER_TENDERS ORDER_TENDERS,
TBL_ORDER_REBATES ORDER_REBATES
);
And for example, take the ORDER_TENDERS type:
create or replace
TYPE ORDER_TENDERS FORCE
AS TABLE OF ORDER_TENDER;
Which contains the rows of tender data:
create or replace
TYPE ORDER_TENDER AS OBJECT
(
TENDER_LINE_ID NUMBER(20,0),
TENDER_CODE VARCHAR2(10),
TENDER_AMT NUMBER(20,0),
UNENCODED_ACCOUNT_NUMBER VARCHAR2(25)
);
So my package I think is working, where I can fill these objects (verified the HEADER stuff working at least.) But I'm not sure how to test/debug/view the results when I call this package to see if I'm getting the ORDER_TENDER/ORDER_TENDERS data...
For example, this works fine:
declare
invar varchar2(5);
outvar ORDERS_TABLE;
O_ORDER_TENDERS ORDER_TENDERS;
O_ORDER_TENDER ORDER_TENDER;
begin
sales_trickler.GetSales(invar, outvar);
FOR i in 1..outvar.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(' record : '
|| to_char(outvar(i).TRANSACTION_NUMBER) || ' '
|| to_char(outvar(i).LOCATION_NUMBER) || ' '
|| to_char(outvar(i).TERMINAL_NAME) || ' '
|| to_char(outvar(i).CUSTOMER_IDENTIFIER));
END LOOP;
end;
But how do I see the ORDER_TENDERS/ORDER_TENDER data?
I tried putting this extra FOR LOOP in, but it doesn't like how I'm referring to ORDER_TENDER(S)...
declare
invar varchar2(5);
outvar ORDERS_TABLE;
O_ORDER_TENDERS ORDER_TENDERS;
O_ORDER_TENDER ORDER_TENDER;
begin
sales_trickler.GetSales(invar, outvar);
FOR i in 1..outvar.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(' record : '
|| to_char(outvar(i).TRANSACTION_NUMBER) || ' '
|| to_char(outvar(i).LOCATION_NUMBER) || ' '
|| to_char(outvar(i).TERMINAL_NAME) || ' '
|| to_char(outvar(i).CUSTOMER_IDENTIFIER));
FOR j in 1..outvar(i).O_ORDER_TENDERS.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('tender record : '
|| to_char(O_ORDER_TENDERS(j).TENDER_AMT) || ' '
);
END LOOP;
END LOOP;
end;
I tried relating to outvar(i).ORDER_TENDERS but that didn't work either... any ideas?
The problem was in the calling code, I shouldn't refer to new instances of the sub-objects, I should refer to them 'as they live' in the original parameter being passed, as such:
tbl_ORDER_LINES ORDER_LINES,
tbl_ORDER_TENDERS ORDER_TENDERS,
TBL_ORDER_REBATES ORDER_REBATES
Here's the actual statement:
declare
invar varchar2(5);
outvar ORDERS_TABLE;
begin
sales_trickler.GetSales(invar, outvar);
FOR i in 1..outvar.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(' record : '
|| to_char(outvar(i).TRANSACTION_NUMBER) || ' '
|| to_char(outvar(i).LOCATION_NUMBER) || ' '
|| to_char(outvar(i).TERMINAL_NAME) || ' '
|| to_char(outvar(i).CUSTOMER_IDENTIFIER));
FOR j in outvar(i).tbl_ORDER_TENDERS.first..outvar(i).tbl_ORDER_TENDERS.last LOOP
DBMS_OUTPUT.PUT_LINE('tender record : '
|| to_char(outvar(i).tbl_ORDER_TENDERS(j).TENDER_AMT) || ' '
);
END LOOP;
--lines
FOR j in outvar(i).tbl_ORDER_LINES.first..outvar(i).tbl_ORDER_LINES.last LOOP
DBMS_OUTPUT.PUT_LINE('line record : '
|| to_char(outvar(i).tbl_ORDER_LINES(j).SKU) || ' '
);
END LOOP;
END LOOP;
end;

PLSQL : Dynamic table record holder

If I want to fetch records from a table (table name is dynamic from input), how to define the record holder or how to fetch the data from this defined table? p_table_name%rowtype will not complie because p_table_name is a parameter, not a table name.
PROCEDURE do_scan(p_table_name IN VARCHAR2
,p_min_num IN NUMBER
,p_time_range IN NUMBER
,p_problem_desc OUT
,p_result_code OUT)
IS
TYPE ObjCurTyp IS REF CURSOR;
v_obj_cursor ObjCurTyp;
v_obj_record ???????(p_table_name%rowtype)
BEGIN
v_stmt_str := 'Select * from :t where date_started > TRUNC(SYSDATE-3)';
OPEN v_obj_cursor FOR v_stmt_str USING p_table_name;
LOOP
FETCH v_obj_cursor INTO v_obj_record;
EXIT WHEN v_obj_cursor %NOTFOUND;
END LOOP;
END do_scan;
You can put that code as a dynamic PL/SQL block within an EXECUTE IMMEDIATE statement.
PROCEDURE do_scan
(
p_table_name IN VARCHAR2
p_min_num IN NUMBER
p_time_range IN NUMBER
p_problem_desc OUT
p_result_code OUT
)
IS
BEGIN
EXECUTE IMMEDIATE
'DECLARE ' ||
' TYPE ObjCurTyp IS REF CURSOR; ' ||
' v_obj_cursor ObjCurTyp; ' ||
' v_obj_record ' || p_table_name || '%rowtype; '||
'BEGIN ' ||
' v_stmt_str := ''Select * from :t where ' ||
' date_started > TRUNC(SYSDATE-3)''; ' ||
' OPEN v_obj_cursor ' ||
' FOR v_stmt_str USING ' ||
p_table_name || '; ' ||
' LOOP ' ||
' FETCH v_obj_cursor INTO v_obj_record; ' ||
' EXIT WHEN v_obj_cursor %NOTFOUND; ' ||
' END LOOP; ' ||
'END;';
END do_scan;
Regards,
Dariyoosh