I have error in above code please help me to solve the above error.
19/4 PLS-00103: Encountered the symbol ";" when expecting one of the
following:
if
The symbol "if" was substituted for ";" to continue.
20/10 PLS-00103: Encountered the symbol "end-of-file" when expecting
one of the following:
begin end function pragma procedure
The code is :-
create or replace package body demo1 is
procedure max(a number , b number) as
begin
if a>b then
DBMS _ output . put _ line('A Is Max..!');
else
DBMS _ output . put _ line('B Is Max..!');
end if;
end;
procedure max(a number , b number , c number) as
begin
if a>b and a>c then
DBMS _ output . put _ line('A Is Max..!');
else if b>c then
DBMS _ output . put _ line('B Is Max..!');
else
DBMS _ output . put _ line('C Is Max..!');
end if;
end;
end demo1;
/
Please Any Help To Solve Above Error..!
Two errors: one is ELSE IF instead of ELSIF (as #astentx commented), and another is your strange way of writing dbms_output.put_line; although you can have spaces around the dot, you can't have it around the underline character. I'd suggest:
No : DBMS _ output . put _ line
Yes: dbms_output.put_line
Once fixed:
Package specification:
SQL> create or replace package demo1 is
2 procedure max(a number , b number) ;
3 procedure max(a number , b number , c number) ;
4 end;
5 /
Package created.
Package body:
SQL> create or replace package body demo1 is
2 procedure max(a number , b number) as
3 begin
4 if a>b then
5 DBMS_output . put_line('A Is Max..!');
6 else
7 DBMS_output . put_line('B Is Max..!');
8 end if;
9 end;
10
11 procedure max(a number , b number , c number) as
12 begin
13 if a>b and a>c then
14 DBMS_output . put_line('A Is Max..!');
15 elsif b>c then --> ELSIF here, not ELSE IF
16 DBMS_output . put_line('B Is Max..!');
17 else
18 DBMS_output . put_line('C Is Max..!');
19 end if;
20 end;
21 end demo1;
22 /
Package body created.
SQL>
Related
Why doesn't this work?
Any advice or solutions are greatly appreciated.
CREATE OR REPLACE TRIGGER OverReading
BEFORE UPDATE OR INSERT ON MeterReadings
FOR EACH ROW
DECLARE
emp_counter INTEGER;
max_meter INTEGER : = 5;
BEGIN
SELECT COUNT(EmployeeId) INTO emp_counter
FROM MeterReadings
WHERE EmployeeId = :NEW.EmployeeId;
IF : OLD.EmployeeId = NEW.EmployeeId THEN
RETURN;
ELSIF emp_counter >= max_meter THEN
raise_application_error(-20900,'Employee are limited to a maximum of 5 meters');
END IF;
END;
/
The Error that is thrown to me
Three syntax errors, all of them related to : character.
When fixed, trigger compiles:
SQL> CREATE OR REPLACE TRIGGER OverReading
2 BEFORE UPDATE OR INSERT ON MeterReadings
3 FOR EACH ROW
4 DECLARE
5 emp_counter INTEGER;
6 max_meter INTEGER := 5; --> here
7 BEGIN
8 SELECT COUNT(EmployeeId) INTO emp_counter
9 FROM MeterReadings
10 WHERE EmployeeId = :NEW.EmployeeId;
11 IF :OLD.EmployeeId = :NEW.EmployeeId THEN --> 2x here
12 RETURN;
13 ELSIF emp_counter >= max_meter THEN
14 raise_application_error(-20900,'Employee are limited to a maximum of 5 meters');
15 END IF;
16 END;
17 /
Trigger created.
SQL>
However: this code will run if you insert rows one-by-one. Otherwise, it will raise mutating table error as you're selecting from the same table you're inserting into (which is not allowed). If that bothers you, there are ways to fix it. Depending on database version you use, it could be a compound trigger or a type + package option.
Write a PL/SQL procedure: when somebody enters a number, it'll print that number. Otherwise, it'll display error message.
You could also try to convert your input string to a number, and then catch the potential conversion error
Create Or Replace Procedure is_number(p_num varchar2) Is
v_num Number;
Begin
v_num := to_number(p_num);
dbms_output.put_line(v_num);
Exception
When VALUE_ERROR Then
dbms_output.put_line(p_num || ' is not a number');
End is_number;
Not too smart, but will get you started.
Using regular expressions (REGEXP_LIKE), check whether value is a number, consisting of
any number of digits [0-9]+
optionally |
followed by a decimal point . (backslash is here to escape it, as dot represents any character in a regular expression)
followed by any number of digits [0-9]+
^ and $ are anchors for beginning and end of entered value (i.e. it must begin and end with a digit)
Here it is:
SQL> create or replace procedure p_test (par_input in varchar2)
2 is
3 begin
4 if regexp_like(par_input, '^[0-9]+|(\.[0-9]+)$') then
5 dbms_output.put_line(par_input);
6 else
7 dbms_output.put_line('Error');
8 end if;
9 end;
10 /
Procedure created.
SQL> set serveroutput on;
SQL>
SQL> begin
2 p_test('2');
3 p_test('2.13');
4 p_test('x');
5 p_test('&#');
6 end;
7 /
2
2.13
Error
Error
PL/SQL procedure successfully completed.
SQL>
You can do it like this,
set serveroutput on;
BEGIN
DBMS_OUTPUT.PUT_LINE('&number'+0);
EXCEPTION
WHEN VALUE_ERROR THEN
DBMS_OUTPUT.PUT_LINE('Error');
END;
/
I am new to PL/SQL and I am stuck on some code.
I am wanting to ask the user for a number and then I want to be able to use this number in an IF THEN statement to verify if the number is greater than or less than 20.
I am stuck on how to obtain user input and once I have it, I can store it and give it back to the user and verify its greater than or less than 20.
DECLARE
a number(2) := 10;
BEGIN
a:= 10;
-- check the boolean condition using if statement
IF( a < 20 ) THEN
-- if condition is true then print the following
dbms_output.put_line('a is less than 20 ' );
END IF;
dbms_output.put_line('value of a is : ' || a);
END;
/
SQL> set serveroutput on; -- for "dbms_output.put_line" to take effect
SQL> DECLARE
a number := &i_nr; -- there's no need to restrict a non-decimal numeric variable to a length
BEGIN
--a:= 10; --no need this when initialization is in declaration section
-- check the boolean condition using if statement
IF( a < 20 ) THEN
-- if condition is true then print the following
dbms_output.put_line('a is less than 20 ' );
END IF;
dbms_output.put_line('value of a is : ' || a);
END;
/
-- it prompts you for value of &i_nr "enter a numeric value, for example 10", for string values it must be in quotes '&i_str'
In SQLPlus, you'd use "&"; in my example, it is && so that I wouldn't have to enter the same value several times (i.e. every time "a" is referenced):
SQL> begin
2 if &&a < 20 then
3 dbms_output.put_line('a is less than 20');
4 end if;
5 dbms_output.put_line('value of a is: ' || &&a);
6 end;
7 /
Enter value for a: 5
old 2: if &&a < 20 then
new 2: if 5 < 20 then
old 5: dbms_output.put_line('value of a is: ' || &&a);
new 5: dbms_output.put_line('value of a is: ' || 5);
a is less than 20
value of a is: 5
PL/SQL procedure successfully completed.
SQL>
Though, I'd say that you'd rather create a procedure with an IN parameter, such as
SQL> create or replace procedure p_test (par_a in number) is
2 begin
3 if par_a < 20 then
4 dbms_output.put_line('a is less than 20');
5 end if;
6 dbms_output.put_line('value of a is: ' || par_a);
7 end;
8 /
Procedure created.
SQL> exec p_test(15);
a is less than 20
value of a is: 15
PL/SQL procedure successfully completed.
SQL> exec p_test(34);
value of a is: 34
PL/SQL procedure successfully completed.
SQL>
How can we define output parameter size in stored procedure?
You can't. Of course, you are in control of how much data you put into the OUT parameter in the stored procedure. If you want you can create a sized local variable to hold the data and then assign the value of that variable to the OUT parameter.
The calling program determines the size of the variable that receives the OUT parameter.
Here is a simple package which declares and uses a subtype:
SQL> create or replace package my_pkg as
2 subtype limited_string is varchar2(10);
3 procedure pad_string (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string);
6 end my_pkg;
7 /
Package created.
SQL> create or replace package body my_pkg as
2 procedure pad_string
3 (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string)
6 as
7 begin
8 p_out_str := rpad(p_in_str, p_length, 'A');
9 end pad_string;
10 end my_pkg;
11 /
Package body created.
SQL>
However, if we call PAD_STRING() in such a way that the output string exceeds the subtype's precision it still completes successfully. Bother!
SQL> var out_str varchar2(128)
SQL>
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str)
PL/SQL procedure successfully completed.
SQL>
SQL> select length(:out_str) from dual
2 /
LENGTH(:OUT_STR)
----------------
12
SQL>
This is annoying but it's the way PL/SQL works so we have to live with it.
The way to resolve the situaton is basically to apply DBC principles and validate our parameters. So, we can assert business rules against the inputs like this:
SQL> create or replace package body my_pkg as
2 procedure pad_string
3 (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string)
6 as
7 begin
8 if length(p_in_str) + p_length > 10 then
9 raise_application_error(
10 -20000
11 , 'Returned string cannot be longer than 10 characters!');
12 end if;
13 p_out_str := rpad(p_in_str, p_length, 'A');
14 end pad_string;
15 end my_pkg;
16 /
Package body created.
SQL>
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str)
BEGIN my_pkg.pad_string('PAD THIS!', 12, :out_str); END;
*
ERROR at line 1:
ORA-20000: Returned string cannot be longer than 10 characters!
ORA-06512: at "APC.MY_PKG", line 9
ORA-06512: at line 1
SQL>
Or we can assert business rules against the output like this:
SQL> create or replace package body my_pkg as
2 procedure pad_string
3 (p_in_str varchar
4 , p_length number
5 , p_out_str out limited_string)
6 as
7 l_str limited_string;
8 begin
9 l_str := rpad(p_in_str, p_length, 'A');
10 p_out_str := l_str;
11 end pad_string;
12 end my_pkg;
13 /
Package body created.
SQL>
SQL> exec my_pkg.pad_string('PAD THIS!', 12, :out_str)
BEGIN my_pkg.pad_string('PAD THIS!', 12, :out_str); END;
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "APC.MY_PKG", line 9
ORA-06512: at line 1
SQL>
In most scenarios we should do both. This is the polite way to build interfaces, because it means other routines can call our procedures with the confidence that they will return the values they say they will.
You could use a subtype in a package header and type check that in the body...
CREATE OR REPLACE PACKAGE my_test
AS
SUBTYPE my_out IS VARCHAR2( 10 );
PROCEDURE do_something( pv_variable IN OUT my_out );
END;
/
CREATE OR REPLACE PACKAGE BODY my_test
AS
PROCEDURE do_something( pv_variable IN OUT my_out )
IS
lv_variable my_out;
BEGIN
-- Work on a local copy of the variable in question
lv_variable := 'abcdefghijklmnopqrstuvwxyz';
pv_variable := lv_variable;
END do_something;
END;
/
Then when you run this
DECLARE
lv_variable VARCHAR2(30);
BEGIN
my_test.do_something( lv_variable );
DBMS_OUTPUT.PUT_LINE( '['||lv_variable||']');
END;
/
You would get the error
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
Seems to go against the spirit of using an out parameter, but after Tony's comment this was the only thing I could think of to control data within the called code.
I have a stored procedure with an IN OUT parameter declared like follows:
create or replace PROCEDURE RIFATT_SEGN0_INS(pIdRifattSegn0 in OUT NUMBER,
pNumDossier IN VARCHAR2 ,
pNumConsegna IN NUMBER,
pDtConsegna IN DATE,
[..]
) AS
[..]
Whenever i call it from another procedure, how do i get the pIdRifattSegn0 parameter that is also out?
Your question isn't entirely clear. An IN OUT parameter is passed both ways, as its name implies. This means it has to be passed a variable, not a literal and you need a declare block to do that. For example:
declare
l_segn number;
begin
l_segn := 1;
-- procedure will have received value = 1
rifatt_segn0_ins(l_segn, 'x', 2, sysdate);
-- procedure may have changed value of l_segn from 1 to something else
dbms_output.put_line(l_segn);
end;
Here is an example:
SQL> create or replace PROCEDURE RIFATT_SEGN0_INS
2 ( pIdRifattSegn0 IN OUT NUMBER
3 , pNumDossier IN VARCHAR2
4 , pNumConsegna IN NUMBER
5 , pDtConsegna IN DATE
6 )
7 as
8 begin
9 dbms_output.put_line(pNumDossier);
10 dbms_output.put_line(to_char(pNumConsegna));
11 dbms_output.put_line(to_char(pDtConsegna,'yyyy-mm-dd'));
12 pIdRifattSegn0 := sqrt(pIdRifattSegn0);
13 end;
14 /
Procedure is aangemaakt.
SQL> create or replace procedure another_procedure
2 as
3 l_IdRifattSegn0 number := 4;
4 begin
5 rifatt_segn0_ins
6 ( pIdRifattSegn0 => l_IdRifattSegn0
7 , pNumDossier => '1A'
8 , pNumConsegna => 42
9 , pDtConsegna => sysdate
10 );
11 dbms_output.put_line('from another_procedure: l_IdRifattSegn0 = ' || to_char(l_IdRifattSegn0));
12 end;
13 /
Procedure is aangemaakt.
SQL> exec another_procedure
1A
42
2009-05-21
from another_procedure: l_IdRifattSegn0 = 2
PL/SQL-procedure is geslaagd.
Regards,
Rob.