I am aware that this has been asked so many times, but my problem doesn't seem to go away. I've already put the delimiter in the correct places but i still keep on getting error 'Error(9,1): Encountered the symbol "/" ' at line 9. If I'm not mistaken, the delimiter that causes the error shold be there.
CREATE OR REPLACE PACKAGE FOR_CLASS_NOV2 AS
PROCEDURE PRINT_SNAME(S_NO S.SNO%TYPE);
FUNCTION FIND_MAX_QTY
RETURN NUMBER;
END;
/
CREATE OR REPLACE PACKAGE BODY FOR_CLASS_NOV2 AS
PROCEDURE PRINT_SNAME(S_NO S.SNO%TYPE) IS
S_SNAME S.SNAME%TYPE;
BEGIN
SELECT SNAME
INTO S_SNAME
FROM S
WHERE SNO = S_NO;
DBMS_OUT.PUT_LINE('SUPPLIER NAME IS: ' || S_NAME);
END PRINT_SNAME;
FUNCTION FIND_MAX_QTY()
RETURN NUMBER IS
M_QTY NUMBER;
BEGIN
SELECT AX(STY)
INTO M_QTY
FROM SP;
RETURN M_QTY;
END FIND_MAX_QTY;
END;
/
I think you should not use parenthesis in the function when there's no parameters.
Try replacing this:
FUNCTION FIND_MAX_QTY()
RETURN NUMBER IS
With this:
FUNCTION FIND_MAX_QTY
RETURN NUMBER IS
Also, you have a variable named S_SNAME but you're printing S_NAME.
Related
create or replace Type e_record AS Object(
e_uid number,
e_first_name varchar2(50) ,
e_last_name varchar2(50),
e_age number,
e_department varchar2(50),
e_designation varchar2(50),
e_salary number
);
create or replace Type e_record_table IS table Of e_record;
Create or replace package E_package
AS
function list_empDetails return e_record_table pipelined;
end E_package;
/
-------Package Body----------
Create or replace package body E_package
AS
Function list_empDetails return e_record_table pipelined
IS
e_ret e_record_table := e_record_table(null,null,null,null,null,null,null);
Begin
for x in(select e_uid,e_first_name,e_last_name,e_age,e_department,e_designation,e_salary into e_ret from Employee_details) Loop
pipe row(e_ret);
End Loop;
return;
end list_empDetails;
end E_package;
/
And the error i m getting is :
Error at line 8: PL/SQL: ORA-00947: not enough values
Error at line 9: PL/SQL: Statement ignored
Error at line 9: PLS-00382: expression is of wrong type
Error at line 8: PL/SQL: SQL Statement ignored
There are a couple of problems with your code.
Firstly, the not enough values error was because you are querying 7 columns and only providing one variable to put them in in the INTO clause. However, you don't use the INTO clause when looping over the results of a query that way, so the first thing you can do is to get rid of it. Your loop variable x will contain each row of data read from your Employee_details table, you don't need another variable for it.
The next thing to note is that you declared e_ret of type e_record_table. Your pipelined function returns e_record_table, but the type of each row you pipe out needs to be the type your table type contains, not the table type. The expression is of wrong type error is because you were attempting to pipe out a value of type e_record_table. Anyway, you're not selecting anything into e_ret any more, so you can just delete this local variable.
Your loop variable x contains each row read from the query. As written, it contains 7 values, so you could create an e_record row to pipe back using something like the following:
pipe row(e_record(x.e_uid, x.e_first_name, x.e_surname, x.e_age, ...));
However, that makes quite a lot of typing since you are repeating the list of columns in your query. You can avoid the duplicated typing by creating the record in the query and then piping that out:
for x in(select e_record(e_uid,e_first_name,e_last_name,e_age,e_department,e_designation,e_salary) as emp from Employee_details) Loop
pipe row(x.emp);
End Loop;
The full working function is below:
Function list_empDetails return e_record_table pipelined
IS
Begin
for x in(select e_record(e_uid,e_first_name,e_last_name,e_age,e_department,e_designation,e_salary) as emp from Employee_details) Loop
pipe row(x.emp);
End Loop;
return;
end list_empDetails;
I wrote the following program:
create or replace procedure ADDPHONE(IDPELATH in number,IDTHLEFWNO in number )
is
cursor cursor_number is select id_pelath ,TelephoneNumber from PhoneNumbers
where id_pelath>2;
more_than_two_numbers exception;
begin
open cursor_number ;
fetch cursor_number into IDPELATH;
if id_pelath%FOUND then raise more_than_two_numbers
end if;
close cursor_number;
exception
when more_than_two_numbers then
raise_application_error('Error');
END;
/
When I run it, I get the following error:
PLS-00103: Encountered the symbol "END" when expecting one of the following: . ;
The symbol ";" was substituted for "END" to continue.
Could you help me to find the error?
There are multiple issues in the procedure.
Input Parameters are never used in the body.
Cursor is declared to fetch two but FETCH statement is only fetching one.
Incorrect usage of raise_application_error,it requires two input arguments.
I have modified the code that should do the job,
CREATE or REPLACE procedure ADDPHONE(IDPELATH in number,IDTHLEFWNO in number)
is
lv_cnt number(10):=0;
more_than_two_numbers exception;
BEGIN
select COUNT(1) INTO lv_cnt
from PhoneNumbers
where id_pelath = IDPELATH
and TelephoneNumber = IDTHLEFWNO;
if (lv_cnt > 2) then
raise_application_error(-20001,'Error - More than two Numbers ');
end if;
EXCEPTION
WHEN OTHERS THEN
raise_application_error(-20002,'An error was encountered - '||SQLCODE||' -ERROR- '||SQLERRM);
END ADDPHONE;
/
I was trying to create a function that given a customer name, get the total balance of that customer's accounts from the account table(A#, CNAME, BAL).
When compiling in command, I got errors:
line "SELECT SUM(bal) INTO total_a_bal FROM account" ignored
and line "WHERE account.cname = v_acname" SQL cmd not properly ended.
Please help correct the errors. Any help would be greatly appreciated!
My function is :
CREATE OR REPLACE FUNCTION totbal
(v_acname IN account.cname%type)
RETURN NUMBER
IS
total_a_bal NUMBER;
BEGIN
SELECT SUM(bal) INTO total_a_bal FROM account
group by account.cname
WHERE account.cname = v_acname;
RETURN total_a_bal;
END;
/
This may not be the only problem with your function, but the WHERE clause always precedes the GROUP BY clause in a SQL query. Hence, your function should look like this:
CREATE OR REPLACE FUNCTION totbal
(v_acname IN varchar2) -- a type should follow IN, e.g. varchar2
RETURN NUMBER
IS
total_a_bal NUMBER;
BEGIN
SELECT SUM(bal) INTO total_a_bal
FROM account
WHERE account.cname = v_acname; -- WHERE always precedes GROUP BY
GROUP BY account.cname
RETURN total_a_bal;
END;
Oracle not only works with the parameter definition "account.cname%type" that is preferred method. What it does is to bind the parameter definition to the column in the database. If the column definition is changed the procedure automatically gets the changed.
This concept of defining in terms of data base columns can (and perhaps should) be extended into the variables and return types of the procedure/function itself.
This function then becomes:
CREATE OR REPLACE FUNCTION totbal
(v_acname IN account.cname%type)
RETURN account.bal%type
IS
total_a_bal account.bal%type;
BEGIN
SELECT SUM(bal) INTO total_a_bal FROM account
group by account.cname
WHERE account.cname = v_acname;
RETURN total_a_bal;
END;
im trying to create 2 package body's in plsql. This is my code:
SET SERVEROUTPUT ON
CREATE OR REPLACE PACKAGE p_locations
AS
FUNCTION f_distance(Lat1 IN NUMBER, Lon1 IN NUMBER, Lat2 IN NUMBER, Lon2 IN NUMBER, Radius IN NUMBER DEFAULT 6387.7) return number;
END p_locations;
/
CREATE OR REPLACE PACKAGE BODY p_locations
AS
FUNCTION f_distance (Lat1 IN NUMBER, Lon1 IN NUMBER, Lat2 IN NUMBER, Lon2 IN NUMBER, Radius IN NUMBER DEFAULT 6387.7)
RETURN NUMBER
IS
-- Convert degrees to radians
DegToRad NUMBER := 57.29577951;
BEGIN
RETURN(NVL(Radius,0) * ACOS((sin(NVL(Lat1,0) / DegToRad) * SIN(NVL(Lat2,0) / DegToRad)) +
(COS(NVL(Lat1,0) / DegToRad) * COS(NVL(Lat2,0) / DegToRad) *
COS(NVL(Lon2,0) / DegToRad - NVL(Lon1,0)/ DegToRad))));
END f_distance;
END p_locations;
/
CREATE OR REPLACE PACKAGE p_winkel
AS
FUNCTION changeOpeningstijd("id" IN number) RETURN boolean;
END p_winkel;
/
CREATE OR REPLACE PACKAGE BODY p_winkel
AS
FUNCTION changeOpeningstijd("id" IN number)
RETURN boolean
IS
dbms_output.put_line('dit is uitgevoerd');
return true;
END changeOpeningstijd;
END p_winkel;
When I run this I gat 3 times a PLS-00103 error. The first is on line 6,16 and says encountered the symbol "." when expecting one of the following: constant exception <an identifier> <a double-quoted delimited-identifier> table long double ref char time timestamp interval date binary national character nchar The symbol "<an identifier>" was substituted for "." to continue.
The strange thing is that when I comment out the 2nd package body everything works fine. Whilst the errors are at the beginning of the first package definition.
Am I doing something stupid wrong here, or can't you create two packages in one session, or what else is going on here, because I don't see any logic in these errors.
You're just missing the BEGIN keyword:
CREATE OR REPLACE PACKAGE BODY p_winkel
AS
FUNCTION changeOpeningstijd("id" IN number)
RETURN boolean
IS
BEGIN ---- this was missing
dbms_output.put_line('dit is uitgevoerd');
return true;
END changeOpeningstijd;
END p_winkel;
/
The line number in the PL/SQL error refers to the PL/SQL block (package, in this case) it is caused by; it isn't the line number in your combined script, as would be the case for a plain SQL error.
When you run this with run script you get three errors reported, not just the one you referred to; and the other two both mention begin:
Errors: check compiler log
6/16 PLS-00103: Encountered the symbol "." when expecting one of the following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table long double ref
char time timestamp interval date binary national character
nchar
The symbol "<an identifier>" was substituted for "." to continue.
8/3 PLS-00103: Encountered the symbol "END" when expecting one of the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
The symbol "begin was inserted before "END" to continue.
9/13 PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
begin end function pragma procedure
As Ben mentioned it's a good idea to add a show errors after each spec/body definition to highlight where an error is seen; but you can also query the user_errors view to see the errors related to each invalid object.
I get the below error while executing code
create or replace
function contact_restriction_function(obj_schema varchar2, obj_name varchar2)
return varchar2 is
v_contact_info_visible hr_user_access.contact_info_visible%type;
begin
-- Here you can put any business logic for filtering
select nvl(max(contact_info_visible),'N')
into v_contact_info_visible
from hr_user_access
where user_name = user;
-- SQL filter / policy predicate
return ''''||v_contact_info_visible||''' = ''Y'' ';
end;
/
after show erros command i got this
show errors
Errors for FUNCTION CONTACT_RESTRICTION:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1 PLS-00103: Encountered the symbol "?" when expecting one of the
following:
begin function pragma procedure subtype type
current cursor delete
exists prior external language
This is the remaining code:
begin
dbms_rls.add_policy(object_schema => 'HR' ,
object_name => 'EMPLOYEES' ,
policy_name => 'Contact_Restriction_Policy' ,
policy_function => 'contact_restriction_function' ,
sec_relevant_cols=>'EMAIL,PHONE_NUMBER'Contact Info ,
sec_relevant_cols_opt=>dbms_rls.all_rows);
end;
below is the actual code which i am executing before show errors:
create or replace function contact_restriction(obj_schema varchar2, obj_name varchar2)
return varchar2
is
v_contact_info_visible IN user_access.contact_info_visible%type;
begin
select nvl(max(contact_info_visible),'N')
into v_contact_info_visible
from user_access where username = user;
return 'v_contact-info_visible ='|| 'Y';
end;
Your original question shows an error message referring to "?", but the code yout posted a as comment would raise a similar error for `"IN"' instead:
2/24 PLS-00103: Encountered the symbol "IN" when expecting one of the following:
That is because you've used IN for a local variable; but IN, OUT and IN OUT are only applicable to stored procedure parameters. You could have declared the function with an explicit IN for example, though it is the default anyway:
create or replace function contact_restriction(obj_schema IN varchar2, ...
So that needs to be removed from the v_contact_info_visible declaration. You've linked to an example you're working from, but you've removed a lot of important quotes from that, which will still cause it to fail when executed as a part of a VPD; because v_contact_info_visible will be out of scope to the caller. And you have a typo, with a hyphen instead of an underscore.
You need something like:
create or replace function contact_restriction(obj_schema varchar2,
obj_name varchar2)
return varchar2 is
v_contact_info_visible user_access.contact_info_visible%type;
begin
select nvl(max(contact_info_visible),'N')
into v_contact_info_visible
from user_access
where username = user;
return ''''||v_contact_info_visible ||''' =''Y''';
end;
/
When called, that will return a string which is either 'N'='Y' or 'Y'='Y'. VPD will include that as a filter in the original query, which will either prevent any rows being returned (in the first case) or have no effect and allow all rows that match any other existing conditions to be returned (in the second case).
The syntax of the function header is incorrect. It should be:
create or replace function contact_restriction(obj_schema IN varchar2, obj_name IN varchar2)
return varchar2
is