Stored procedure ERROR in Oracle - sql

create or replace PROCEDURE Getstudentname(
#firstname varchar(20),
#lastname varchar (20),
#e_mail varchar(20)
)
as
begin
insert into TBL_STUDENTS(fanme, lname, email)
values(#firstname, #lastname, #e_mail);
end;
What can be the error in this procedure?
Procedure GETSTUDENTNAME compiled
Errors:
check compiler log
And this SQL query is also not working giving:
Error report - SQL Error: ORA-00936: missing expression
00936. 00000 - "missing expression"
*Cause:
*Action:

Oracle doesn't use # for parameters. I would highly recommend that you prefix them with something, to distinguish them from column names. Something like this:
create or replace PROCEDURE Getstudentname (
in_firstname varchar2,
in_lastname varchar2,
in_e_mail varchar2
)
as
begin
insert into tbl_students(fname, lname, email)
values(in_firstname, in_lastname, in_e_mail);
end;
In addition, Oracle does not require a length for string parameters, and varchar2 is the standard variable string type. Your code looks more like SQL Server code than Oracle code.

try this
create or replace PROCEDURE Getstudentname(
firstname in varchar2,
lastname in varchar2,
e_mail in varchar2
)
as
begin
insert into TBL_STUDENTS(fanme,lname,email)values(firstname,lastname,e_mail);
end;

Correct the typos and use the right syntax:
CREATE TABLE tbl_Students
( id int, Fname varchar(20), Lname varchar(20),Email varchar(20) );
create or replace PROCEDURE Getstudentname(
firstname in tbl_students.fname%TYPE,
lastname in tbl_students.lname%TYPE,
e_mail in tbl_students.email%TYPE
)
as
begin
insert into TBL_STUDENTS (fname,lname,email) values (firstname,lastname,e_mail );
end;
/

Related

Pl SQL Oracle PLS-00103: Encountered the symbol "CREATE"

this code takes input for zipcode, city, and state and then inserts that into the table created Address. Prior to inserting data it will check if the zipcode is already in the table, if so calling procedure(error) to display an error code.
Im getting an error code pls-00103: encountered the symbol "CREATE" when trying to execute the code. Here is my code so far. Thanks for any help in advance.
drop table address;
create table address(zipcode NUMBER, city varchar2(30), state varchar2(20));
create or replace procedure error as
begin
dbms_output.put_line('Error Zip Code already found in table');
end error;
declare
zzip number;
ccity varchar2(30);
sstate varchar2(30);
create or replace procedure location(p_zipcode NUMBER,
p_city varchar2,
p_state varchar2) is
zip address.zipcode%type;
cit address.city%type;
st address.state%type;
begin
select count(*) from address into zip where zipcode = zip;
if any_rows_found then
error;
else
Insert into address values(zip, cit, st);
end if;
end location;
begin
select &zipcode into zzip from dual;
select &city into ccity from dual;
select &state into sstate from dual;
procedure location(zzip, ccity, sstate);
end;
/
I'm not sure what you're trying to do, but the following may be closer to what you had in mind:
drop table address;
create table address(zipcode NUMBER, city varchar2(30), state varchar2(20));
declare
zzip number;
ccity varchar2(30);
sstate varchar2(30);
procedure error is
begin
dbms_output.put_line('Error Zip Code already found in table');
end error;
procedure location(p_zipcode NUMBER, p_city varchar2, p_state varchar2) is
zip_count NUMBER;
begin
select count(*)
into zip_count
from address
where zipcode = p_zipcode;
if zip_count > 0 then
error;
else
Insert into address
(zipcode, city, state)
values
(p_zipcode, p_city, p_state);
end if;
end location;
begin
select &zipcode into zzip from dual;
select &city into ccity from dual;
select &state into sstate from dual;
location(zzip, ccity, sstate);
end;
/
Best of luck.
I dont know if I understand your problem correctly, but there are certain correction I'd like to address to answer your problem
First, if you are going to create a procedure/function, do it in a separate worksheet then compile it. Dont compile it together with other anonymous blocks because most of the time, if you dont end your other blocks with '/', errors will surely generate.
Second, your DECLARE statement is misplaced, if you are going to make an anonymous block, make sure DECLARE, BEGIN and END are in line, dont create a procedure/function inside an anonymous block.
Third, you are declaring variables in your procedures and using them but doesnt have an initial value, so it will just pass a null value to the DML statement in your procedure. just use the parameter directly.
Fourth, avoid creating a procedure that only contains dbms_output.put_line. Its silly.
Lastly, your anonymous block that should be calling your procedure, uses '&', please avoid using '&' inside pl/sql as '&' is a feature in SQL*Plus and doesnt have any meaning in PL/SQL, instead, you can use ':' as for binding variables. But you use '&' not in binding variables so you should remove that;
Try this:
drop table address;
/
create table address(zipcode NUMBER, city varchar2(30), state varchar2(20));
/
create or replace procedure location(p_zipcode NUMBER,
p_city varchar2,
p_state varchar2) is
zip address.zipcode%type;
begin
select count(*)
from address
into zip
where zipcode = p_zipcode
and city =p_city
and state = p_state;
if zip > 0 then
dbms_output.put_line('Error Zip Code already found in table');
else
Insert into address values(p_zipcode, p_city, p_state);
end if;
end location;
/
begin
location(:zzip, :ccity, :sstate);
end;

Stored Procedure Select

Well, i've been trying to built a SP in order to help me get all the fields from a table called TIKEt here is my table TIKET:
TABLE TIKET:
IDTIKET TYPE NUMBER
NOMBRE TYPE VARCHAR2
EDITORIAL TYPE VARCHAR2
AUTOR TYPE VARCHAR2
EDICION TYPE VARCHAR2
PRECIO TYPE NUMBER
CANTIDAD TYPE NUMBER,
FECHA TYPE DATE default sysdate
NOMBRE_USER TYPE VARCHAR2
and here it's my SP code:
`create or replace procedure get_tiket
(
idtiket_ out number,
nombres_ out varchar2,
editorial_ out varchar2,
autor_ out varchar2,
edicion_ out varchar2,
precio_ out number,
cantidad_ out number,
fecha_ out date,
nombre_user_ in varchar2
)
is
begin
select idtiket, nombre, editorial, autor, edicion, precio, cantidad, fecha into idtiket_, nombres_, editorial_, autor_, edicion_, precio_, cantidad_, fecha_ from tiket
where nombre_user=nombre_user_;
end;
/`
When i run this code in SQLPLus says: "Procedure Created" which i think means it's ok right? But when i called this Sp: exec get_tiket('ale'); it gives me this error:
call get_tiket('ale');
ERROR at line 1:
ORA-06553: PLS-306: wrong number or types of arguments in call to 'GET_TIKET'
What i want is to get all the fields from table TIKET depending on the user i need! Please thanks for your help ahead!
You have bunch of out parameters in stored procedure, and you have to pass them as well :
DECLARE idtiket number;
-- other variables
BEGIN
EXEC get_tiket(idtiket, ..... 'ale');
END;
Also, I guess function will work better than procedure in this case...

Procedure to insert employees: PL/SQL statement ignored

I am trying to insert values into an Employees table using the following procedure. I'm getting errors. Can anyone please explain the problem to me? Error code: Line 29: SQL statement ignored.
CREATE OR REPLACE PROCEDURE insert_employee(
p_emp_id IN NUMBER,
p_emp_fname IN VARCHAR2,
p_emp_sname IN VARCHAR2,
p_emp_add1 IN VARCHAR2,
p_emp_add2 IN VARCHAR2,
p_emp_town IN VARCHAR2,
p_emp_county IN VARCHAR2,
p_emp_telno IN NUMBER,
p_emp_position IN VARCHAR2,
p_emp_manager IN VARCHAR2
) IS
v_county_id County.county_id%type;
v_position_id Positions.position_id%type;
v_manager_id Facilities.facilty_id%type;
BEGIN
SELECT county_id
INTO v_county_id
FROM County WHERE county_name = p_emp_county;
SELECT position_id
INTO v_position_id
FROM Positions WHERE position_name = p_emp_position;
SELECT facility_manager
INTO v_manager_id
FROM Facilities WHERE facility_name = p_emp_manager;
INSERT INTO Employees (emp_id, emp_fname, emp_sname, emp_add1, emp_add2, emp_town, emp_county, emp_telno, emp_position, emp_salary, emp_manager)
VALUES(p_emp_id, p_emp_fname, p_emp_sname, p_emp_add1, p_emp_add2, p_emp_town, v_county_id, p_emp_telno, v_position_id, p_emp_salary, v_manager_id);
END;
/
Remove the SELECTs - they are in invalid syntax, and don't do anything necessary here anyway. ALso remove the pointless error "handler" which does nothing more than hide the error:
CREATE OR REPLACE PROCEDURE insert_employee(
p_emp_id IN NUMBER,
p_emp_fname IN VARCHAR2,
p_emp_sname IN VARCHAR2,
p_emp_add1 IN VARCHAR2,
p_emp_add2 IN VARCHAR2,
p_emp_town IN VARCHAR2,
p_emp_county IN VARCHAR2,
p_emp_telno IN NUMBER,
p_emp_position IN VARCHAR2,
p_emp_manager IN VARCHAR2
) IS
BEGIN
INSERT INTO Employees (emp_id, emp_fname, emp_sname, emp_add1, emp_add2, emp_town, emp_county, emp_telno, emp_salary, emp_position, emp_manager)
VALUES(p_emp_id, p_emp_fname, p_emp_sname, p_emp_add1, p_emp_add2, p_emp_town, p_emp_county, p_emp_telno, p_emp_salary, p_emp_position, p_emp_manager);
END;
If your example has been oversimplified and you actually need the values you were selecting before (e.g. you insert those into Employees also) then you need to use "select into" syntax e.g.
...
) IS
v_county_id county.county_id%type;
v_xxx county.xxx%type;
BEGIN
SELECT county_id
INTO v_county_id
FROM County WHERE county_name = p_emp_county;
...
Your local variable declarations should have semicolons at the end of each line:
) IS
v_county_id County.county_id%type;
v_position_id Positions.position_id%type;
v_manager_id Facilities.facilty_id%type;
Do you need to select into a cursor or a variable?
E.g.
SELECT county_id into v_country
FROM County WHERE county_name = p_emp_county;
you should type ; after variable definition instead comma.
check column name
v_manager_id Facilities.facilty_id%type;
FROM Facilities WHERE facility_name = p_emp_manager;
create or replace procedure procOne(sid OUT number,sname OUT varchar,fee OUT number)
as
begin
insert into student values(sid,sname,fee);
end;

Stored Function in Oracle not Inserting Values into the desired table

Here is my Code given below. I am trying to add 5 parameters which the function takes into the table Employee. But I am not successful in doing it and have tried a lot of things.
Error
ORA-01858: a non-numeric character was found where a numeric was
expected ORA-06512: at "xxxxxxx.A1SF_ADDEMP", line 14
01858. 00000 - "a non-numeric character was found where a numeric was expected"
*Cause: The input data to be converted using a date format model was
incorrect. The input data did not contain a number where a number was
required by the format model.
*Action: Fix the input data or the date format model to make sure the
elements match in number and type. Then retry the operation.
Plus how do I test a Stored function that has a Insert/Update or Delete Statement in it?
Execution Statement
Select A1SF_ADDEMP('Adesh', '33', 'M', 8000, '26/03/1990')
From dual;
Code
CREATE OR REPLACE Function A1SF_ADDEMP
(pEmpName In Varchar2,
pTaxFileNo In Varchar2,
pGender In Varchar2,
pSalary In Number,
pBirthdate In Varchar2
) Return Varchar2
Is
tEmpId Number(38,0);
tBirthDate Date;
BEGIN
tEmpId := A1Seq_Emp.nextval;
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate)
Values (tEmpId, pEmpName, pTaxFileNo, pGender, pSalary, tBirthdate);
Commit;
Return null;
END;
Firstly you cannot call a function with DML in it in a select statement. You have to assign the output to a variable in a PL/SQL block, something like:
declare
l_output number;
begin
l_output := my_function(variable1, variable2);
end;
It's bad practice to do DML in a function; partly because it causes the errors you're coming across. You should use a procedure as detailed below. The other reason for this is that you're as always returning null there's no need to return anything at all!
create or replace procedure my_procedure ( <variables> ) is
begin
insert into employees( <columns> )
values ( <values > );
end;
The specific reason for your error is this line:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
pBirthdate is already a string; by putting a ' around it you're passing the string 'pBirthdate' to the function to_date and Oracle can't convert this string into a day, month or year so it's failing.
You should write this as:
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
You also don't need to specify number(38,0), you can just write number instead.
It is possible to return a value from a procedure using the out keyword. If we assume that you want to return empid you could write is as something like this:
create or replace procedure A1SF_ADDEMP (
pEmpName in varchar2
, pTaxFileNo in varchar2
, pGender in varchar2
, pSalary in number
, pBirthdate in varchar2
, pEmpid out number
) return varchar2 is
begin
pempid := A1Seq_Emp.nextval;
Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate)
Values ( pEmpId, pEmpName, pTaxFileNo, pGender
, pSalary, to_date(pBirthdate,'dd/mm/yyyy');
end;
To just execute the procedure call it like this:
begin
A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
If you want to return the empid then you can call it like this:
declare
l_empid number;
begin
l_empid := A1SF_ADDEMP( EmpName, TaxFileNo, Gender
, Salary, Birthdate);
commit;
end;
Notice how I've moved the commit to the highest level, this is to avoid committing stuff in every procedure when you might have more things you need to do.
Incidentally, if you're using Oracle 11g then there's no need to assign the value A1Seq_Emp.nextval to a variable. You can just insert it directly into the table in the values list. You, of course won't be able to return it, but you could return A1Seq_Emp.curval, as long as there's nothing else getting values from the sequence.
You should use a procedure (instead of a function) if you are not returning any values.
If you look at the line mentioned in the error message you can spot your error:
tBirthdate := to_date('pBirthdate','dd/mm/yyyy');
You are passing the string literal 'pBirthdate' to the to_date() call. But you want to pass the parameter, so it should be
tBirthdate := to_date(pBirthdate,'dd/mm/yyyy');
(note the missing single quotes arount pBirthdate).
So as a procedure the whole thing would look like this:
CREATE OR REPLACE PROCEDURE A1SF_ADDEMP
(pEmpName In Varchar2,
pTaxFileNo In Varchar2,
pGender In Varchar2,
pSalary In Number,
pBirthdate In Varchar2
)
IS
BEGIN
Insert Into Employee(EmpId, EmpName, TaxFileNo, Gender, Salary, Birthdate)
Values (A1Seq_Emp.nextval, pEmpName, pTaxFileNo, pGender, pSalary, to_date(pBirthdate,'dd/mm/yyyy'));
Commit;
END;
To run it:
execute A1SF_ADDEMP('Adesh', '33', 'M', 8000, '26/03/1990');
In your situation you need to use procedure with out parameter where your out param is your returning param that contains your desirable value. This is I think best practice in this situation when you want to use DML in select statement.
Second way to do it but its not a good practice is to use one function like yours but before return a value you need to use if statement to check what is the value and if value is what you desire to call in this if statement PRAGMA AUTONOMOUS_TRANSACTION procedure which will do your DML independently of function calling to it. For more information about pragma transactions your can read here:
http://docs.oracle.com/cd/B19306_01/appdev.102/b14261/autonotransaction_pragma.htm
Best Regards and hope I was helpful

Calling a member procedure in Oracle 11g

Lets say i have:
create type address as object (
line1 varchar2(50),
city varchar2(50),
member procedure insert_address(line1 varchar2, city varchar2)
)
/
create table address_table of address;
create type body address as
member procedure insert_address(line1 varchar2, city varchar2) is
begin
insert into address_table values (line1, city);
commit;
end insert_address;
end;
/
How do i call insert_address?
By doing the following i get invalid number or types of arguments
begin
address.insert_address('123 my road','london');
end;
i can do this and it works, but seems like a bad idea:
declare
v_address address := new address(null,null);
begin
v_address.insert_address('123 my road','london');
end;
Thanks
Use static instead of member for your procedure:
static procedure insert_address(line1 varchar2, city varchar2)
Then you can call it on the object type instead of the instance:
address.insert_address('123 my road','london');
See Using PL/SQL Object Types for more information.
As you have built it (which is bizarrely), the procedure insert_address can only be called in the context of an object of type address, and must be called with parameters line1 and city, with values that have no connection with the object you called it "for". This is how I would build the table and code, and use it:
create table address_table (line1 varchar2(50), city varchar2(50));
create package address_pkg as
procedure insert_address(p_line1 varchar2, p_city varchar2);
end;
/
create package body address_pkg as
procedure insert_address(p_line1 varchar2, p_city varchar2) is
begin
insert into address_table (line1, city) values (p_line1, p_city);
end;
end;
/
exec address_pkg.insert_address ('123 my road', 'london');
With your funkier model, it seems that the insert_address procedure should insert "the address object itself" into the table. Something like:
create type address as object (
line1 varchar2(50),
city varchar2(50),
member procedure insert_address
)
/
create table address_table of address;
create type body address as
member procedure insert_address is
begin
insert into address_table values (line1, city);
commit;
end insert_address;
end;
/
Then the insert would be like:
declare
v_address address := new address('123 my road','london');
begin
v_address.insert_address;
end;