Error compiling Oracle stored procedure - sql

I have written this stored procedure:
CREATE OR REPLACE PROCEDURE ADD_EMPLOYEE
(
F_FNAME IN VARCHAR2
, L_NAME IN VARCHAR2
, EMAIL IN VARCHAR2
, jobid IN VARCHAR2 DEFAULT 'SA_REP'
, MGR IN employees.manager_id%type DEFAULT 145
, SAL IN employees.salary%type DEFAULT 1000
, COMM IN EMPLOYEES.COMMISSION_PCT%type DEFAULT 0
, DEPTID IN VARCHAR2 DEFAULT 30
, HIRE_DATE IN DATE
)
AS
BEGIN
insert into EMPLOYEES(employee_id,first_name,last_name,email,hire_date,salary,commission_pct,manager_id,department_id)
values
(employees_seq.nextval,f_name,l_name,email,HIRE_DATE,sal,comm,mgr,deptid);
END ADD_EMPLOYEE;
It gives the message
sql statement ignored.
columns not allowed here.
What is wrong with it?

Rename parameters email and hire_date.
Also, it is handy to name parameters as it's corresponding columns with additional prefix 'p_'. In your case:
employee_id -> p_employee_id
first_name -> p_first_name
...
department_id-> p_department_id.
If you declare local variable, you can use 'v_' prefix.

Related

Inserting XML data into Oracle table

I have a table that contains XML of HUGECLOB data type, I need to extract CLOB data as XML and get some specific XML tag value to insert it into another table.
I used dbms_lob to get XML and the following is my code to insert XML into another table.
create or replace procedure xml_into_table(l_xml in xmltype)
as
begin
insert into emp( EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPT)
SELECT * FROM xmltable('employees' passing l_xml
columns EMPNO NUMBER PATH ' /employee/empno',
ENAME VARCHAR2 PATH '/employee/ename',
JOB VARCHAR2 PATH '/employee/job',
HIREDATE DATE PATH '/employee/hiredate');
END;
/
Error(7,56): PL/SQL: ORA-00906: missing left parenthesis.
Can some one please guide me, what is the right way for achieving this.
The VARCHAR2 data type needs a size and you are missing the columns MGR, SAL, COMM and DEPT so SELECT * will only get 4 columns and not the 8 you have named in the INSERT.
create or replace procedure xml_into_table(l_xml in xmltype)
as
begin
insert into emp( EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPT)
SELECT empno,
ename,
job,
NULL,
hiredate,
NULL,
NULL,
NULL
FROM xmltable(
'employees'
passing l_xml
columns
EMPNO NUMBER PATH ' /employee/empno',
ENAME VARCHAR2(200) PATH '/employee/ename',
JOB VARCHAR2(200) PATH '/employee/job',
HIREDATE DATE PATH '/employee/hiredate'
);
END;
/

please find the solution of this problem. ( in PL SQL ) --------

I'm doing an assignment and the last question states that I call the procedure from question 2 and function from question 3 and then put them in an insert clause(question 4).
Write a PL/SQL Code for an anonymous block to do the following (in package):
a) Get the doctor name for a given doctor id (read from keyboard)
using a function [FunGetDoctorName].
b) Get the department name for a given department id (read from
keyboard) using a procedure [ProGetepartmentName].
c) Insert the doctor name and department name (which you got from the
function and
procedure) by including serial number and current date into the
visitings table.
put the answer in ( Package)
this is my table codes:
CREATE TABLE DEPT(
DeptNo NUMBER PRIMARY KEY,
DeptName VARCHAR2(30) NOT NULL);
CREATE TABLE DOCTORS(
DoctorID NUMBER PRIMARY KEY,
DoctorNAME VARCHAR2(30) NOT NULL,
DeptNo NUMBER REFERENCES DEPT(DEPTNO),
Salary NUMBER NOT NULL);
CREATE TABLE VISITINGS(
SlNo NUMBER PRIMARY KEY,
DoctorName VARCHAR2(30),
DepartmentName VARCHAR2(30),
VisitDate DATE);
INSERT INTO DEPT VALUES(10,'ENT');
INSERT INTO DEPT VALUES(20,'Orthopedic');
INSERT INTO DEPT VALUES(30,'Cardiology');
INSERT INTO DEPT VALUES(40,'Neurology');
INSERT INTO DOCTORS VALUES(101,'Abheer',20,2550);
INSERT INTO DOCTORS VALUES(102,'Zuwaina',10,2175);
INSERT INTO DOCTORS VALUES(103,'Sara',30,1985);
INSERT INTO DOCTORS VALUES(104,'Fatma',20,2200);
INSERT INTO DOCTORS VALUES(105,'Laila',10,2600);
INSERT INTO VISITINGS VALUES(1,'Sara','Cardiology','10-Nov-19');
INSERT INTO VISITINGS VALUES(2,'Abheer','Orthopedic','11-Nov-19');
My function
create or replace function FunGetDoctorName(Docid number) return varchar2 is
docname DOCTORS.DoctorName%type;
Begin
select DoctorName into docname from DOCTORS where DoctorID = Docid;
return docname;
End ;
/
My procedure
create or replace procedure ProGetDepartmentName is
depname dept.DeptName%type;
Begin
select DeptName into depname from dept where DeptNo =10;
dbms_output.put_line(depname);
End ;
/
here is the problem:
Create or replace package pkg1 is
Function FunGetDoctorName(Docid Number) return varchar2 ;
procedure ProGetDepartmentName(DeptNo NUMBER);
end pkg1;
/
CREATE OR REPLACE PACKAGE BODY pkg1 AS
FUNCTION FunGetDoctorName(Docid Number)
RETURN varchar2 IS
docname DOCTORS.DoctorName%type;
BEGIN
select DoctorName into docname from DOCTORS where DoctorID = Docid;
return docname ;
END;
PROCEDURE ProGetDepartmentName(DeptNo NUMBER) IS
depname dept.DeptName%type;
BEGIN
Select DeptName into depname from dept where DeptNo=10;
dbms_output.put_line(depname) ;
END;
END pkg1 ;
/
declare
ProGetDepartmentName
(:DeptNo in dept.DeptNO%type,
depname in dept.DeptName%type)
FunGetDoctorName
(:Docid in DOCTORS.DoctorID%type ,
docname in DOCTORS.DoctorName%type);
docname varchar2(30);
depname varchar2(30);
Docid number;
serial number;
is
Begin
dbms_output.put_line('Department Name: '||depname);
select count(slno) into serial from visitings;
serial :=serial+1;
insert into visitings(slno,doctorname,departmentname,visitdate) values(serial,docname,depname,sysdate);
End;
/
I keep getting errors :
SP2-0552: Bind variable "DOCID" not declared.
First of all, your procedure must have one in and one out parameter so that you can pass deptno and get deptname as the output.
procedure ProGetDepartmentName(p_depnum number,P_depname out varchar)
is
Begin
select DeptName into P_depname from dept where DeptNo = p_depnum;
dbms_output.put_line(p_depnum);
End ;
/
In your pl/sql block, you can use substitution variable to take an input from keyboard as follows:
declare
V_DeptNo dept.DeptNO%type := &dept_no
V_deptname in dept.DeptName%type;
V_Docid in DOCTORS.DoctorID%type := &doc_id;
is
Begin
Pkg1.ProGetDepartmentName(v_deptno, v_deptname);
dbms_output.put_line('Department Name: '|| v_deptname);
insert into visitings(slno,doctorname,departmentname,visitdate)
values((select count(slno) + 1 from visitings),FunGetDoctorName(v_docid),v_deptname,sysdate);
End;
/
Note:
Instead of fetching count from table and adding one into it for slno, you should use the sequence.
In procedure and function, use exception block to handle no row found or multiple record found or any other issues gracefully.
While inserting in to table, you should also use exceprion block to handle issues gracefully. (In your case it is needed because of the count(slno) + 1 logic as it can assign same number to different sessions executing simentaneously which my lead to primary key violation)

Insert Data Into Table with Stored Procedure in Oracle SQL

I am working through a homework assignment and am stuck on a problem with stored procedures.
I have the following tables:
create table Restaurant(rID int, name varchar2(100), address varchar2(100), cuisine varchar2(100));
create table Reviewer(vID int, name varchar2(100));
create table Rating(rID int, vID int, stars int, ratingDate date);
For my stored procedure I need to create, I get an input of a restaurant name (unique), reviewer name(unique), star rating, and review date. I need to update the Rating table with the proper information, and add a new reviewer to the Review table if they have not previously existed in the table.
In order to start my stored procedure, I wanted to start with just creating a new table called newReview to get the inputs stored in a new table, before re-writting to update the existing tables.
Here is the newReview Table
CREATE TABLE newReview(
RestaurantName VARCHAR(100),
UserName VARCHAR(100),
Stars Int,
RatingDate Date
)
This is my AddNewReview procedure, which compiles with success:
CREATE OR REPLACE PROCEDURE AddNewReview(
RESTAURANTNAME IN VARCHAR2 (100)
, USERNAME IN VARCHAR2 (100)
, Stars IN NUMBER
, RATINGDATE IN DATE
) AS
BEGIN
INSERT INTO newReview VALUES (RestaurantName, UserName, Stars, RatingDate);
END AddNewReview;
;
However, when I run the stored procedure with inputs as such,
BEGIN
AddNewReview ('Rangoli', 'Sarah M.', 4, '2020-11-21');
END;
I get the following error:
Error starting at line : 20 in command -
BEGIN
AddNewReview ('Rangoli', 'Sarah M.', 4, '2020-11-21');
END;
Error report -
ORA-06550: line 2, column 5:
PLS-00905: object TOCONN22.ADDNEWREVIEW is invalid
ORA-06550: line 2, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I have tried defining the date input as DATE '2020-11-21' and also switching the single quote to double. Where am I going wrong, as this is the first stored procedure I am writing.
Try to change Stars data type from NUMBER to Int
AS:
CREATE OR REPLACE PROCEDURE AddNewReview(
RESTAURANTNAME IN VARCHAR2 (100)
, USERNAME IN VARCHAR2 (100)
, Stars IN NUMBER
, RATINGDATE IN DATE
) AS
BEGIN
INSERT INTO newReview VALUES (RestaurantName, UserName, Stars, RatingDate);
END AddNewReview;
;
to
CREATE OR REPLACE PROCEDURE AddNewReview(
RESTAURANTNAME IN VARCHAR2 (100)
, USERNAME IN VARCHAR2 (100)
, Stars IN Int
, RATINGDATE IN DATE
) AS
BEGIN
INSERT INTO newReview VALUES (RestaurantName, UserName, Stars, RatingDate);
END AddNewReview;
;
You need to look up the ids for the insertion:
CREATE OR REPLACE PROCEDURE AddNewReview (
in_RESTAURANTNAME IN VARCHAR2(100),
in_USERNAME IN VARCHAR2(100),
in_Stars IN NUMBER,
in_RATINGDATE IN DATE
) AS
BEGIN
INSERT INTO newReview (rid, vid, stars, RatingDate)
SELECT r.id, rr.id, in_stars, in_RatingDate
FROM restaurant r JOIN
reviewer rr
ON r.name = in_RestaurantName AND
rr.name = in_UserName
END AddNewReview;
This joins to the reference tables to get the ids you need. It will not insert the review if either name does not match. Your question doesn't specify what to do in that case, so that seems like reasonable behavior.
Note that the parameters are named so they don't conflict with column names. And this has listed all columns for the insert -- both are best practices.
Parameters are defined only by name and data type, they do not contain size specification. So your procedure needs:
create or replace procedure addnewreview(
restaurantname in varchar2
, username in varchar2
, stars in int
, ratingdate in date
...
You need to use To_Date function while calling the stored procedure, like below
BEGIN
AddNewReview ('Rangoli', 'Sarah M.', 4, TO_DATE('2020-11-21','YYYY-MM-DD'));
END;

Calling a sql procedure inside another procedure

I want to call a procedure inside another procedure when some conditions met. I am facing a problem when calling the procedure inside another procedure.
Please help me to get this issue resolved.
--- First Procedure ----
create or replace
PROCEDURE first_procedure(
PERIDTYPE IN VARCHAR2,
CITIZENID IN NUMBER,
NIFNUMBER OUT NUMBER,
PERIDNUMBER1 OUT NUMBER,
NUBINUMBER OUT NUMBER ,
REGFORMID OUT NUMBER ,
BOSTATUSCODE OUT VARCHAR2 ,
PERID OUT NUMBER )
AS
BEGIN
SELECT cm_nu_bi
INTO NUBINUMBER
FROM cm_minjus_agt_vw
WHERE cm_id_citizen_stage_sigt = CITIZENID;
select per_id
into PERID
from ci_per_id
WHERE id_type_cd = PERIDTYPE
AND per_id_nbr = NUBINUMBER;
SELECT reg_form_id,
per_id_nbr,
bo_status_cd
INTO REGFORMID,
NIFNUMBER,
BOSTATUSCODE
FROM table_x
WHERE per_id= PERID;
if NIFNUMBER is not null then
INSERT
INTO table_y
(
id_cidadao_stage_sigt,
NU_NIF
)
VALUES
(
PERIDNUMBER,
NIFNUMBER
);
else
EXCE := CM_ERROR_TABLE_ENTRY #CITIZENID=CITIZENID, #REGID=REGFORMID;
end if;
END CM_GET_NIF_NBR;
--- Second Procedure ---
create or replace
PROCEDURE second_procedure
(
CITIZENID IN NUMBER
, REGID IN NUMBER
, EXCEPTIONCATEGORYCD IN OUT VARCHAR2
, MESSAGECATEGORYNUMBER IN OUT NUMBER
, MESSAGENUMBER IN OUT NUMBER
, MESSAGETEXT IN OUT VARCHAR2
) AS
BEGIN
select
message_cat_nbr,
message_nbr,
excp_cat_cd
into
MESSAGECATEGORYNUMBER,
MESSAGENUMBER,
EXCEPTIONCATEGORYCD
from ci_reg_form_excp where
reg_form_id= REGID;
SELECT
message_text
into
MESSAGETEXT
FROM ci_msg_l
WHERE message_cat_nbr=MESSAGECATEGORYNUMBER
AND message_nbr=MESSAGENUMBER
AND language_cd='PTG';
insert INTO tb_sigt_processing_log#MINJUS_AGT_DBLINK
(ID_CIDADAO_STAGE_SIGT,exception_cat_code, message_category, message_number, message_text)
values
(CITIZENID,EXCEPTIONCATEGORYCD,MESSAGECATEGORYNUMBER,MESSAGENUMBER,MESSAGETEXT);
NULL;
END CM_ERROR_TABLE_ENTRY ;
The issue i am getting is. Please tell me if more input is needed.
I think you want to call the procedure with arguments in this line
EXCE := CM_ERROR_TABLE_ENTRY #CITIZENID=CITIZENID, #REGID=REGFORMID;
It is not valid in Oracle. You could just call your procedure using
CM_ERROR_TABLE_ENTRY( CITIZENID,REGFORMID );

getting error in below code

I am getting missing parenthesis error in below for REPLACE function
declare
file_name varchar2(10):= 'emp.csv';
begin
execute immediate 'CREATE TABLE emp_external
(
EMPNO NUMBER(4),
emp_name varchar2(100),
HIREDATE DATE
)
ORGANIZATION EXTERNAL
(TYPE ORACLE_LOADER
DEFAULT DIRECTORY import
ACCESS PARAMETERS
(RECORDS DELIMITED BY NEWLINE
LOAD WHEN
(HIREDATE != BLANKS )
fields terminated by '''||','||'''
( EMPNO,
replace(emp_name,'''||'"'||','||''||'''),
HIREDATE DATE '||'yyyymmdd'||'
)
)
LOCATION ('''||file_name||''')
)
REJECT LIMIT UNLIMITED';
end;
when i am querying the external table .its giving me the error "EMP_NAME" is bad identifier
I'm not used to plsql but don't you miss a comma ?
EMPNO NUMBER(4),
emp_name varchar2(100),<------ Here ?
HIREDATE DATE
)