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
)
Related
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;
/
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)
I've created this procedure
create or replace procedure enrollstudent(
rno in STUDENTS.ROLL_NUMBER%type,
sname in STUDENTS.STUDENT_NAME%type,
cid in STUDENTS.COURSEID%type,
cfees in STUDENTS.FEES%type,
spercent in students.percentage%type
)as
discount number;
begin
discount := spercent*5;
cfees := cfees-discount;
insert into STUDENTS values(rno, sname, cid, cfees, spercent);
commit;
end;
that works with this table
CREATE TABLE STUDENTS(
ROLL_NUMBER NUMBER(20) NOT NULL,
STUDENT_NAME VARCHAR2(25) NOT NULL,
COURSEID NUMBER(20) NOT NULL,
FEES NUMBER(20) ,
PERCENTAGE NUMBER(20)
);
When I run the procedure creation I have a Procedure ENROLLSTUDENT compiled and it gets created but i have the following errors in the compiler log
Error(8,1): PL/SQL: Statement ignored
Error(8,1): PLS-00363: expression 'CFEES' cannot be used as an assignment target
If I try to run the procedure with some data I simple have PLS-00905: object [schema].ENROLLSTUDENT is invalid
CFEES is an IN parameter. You can't change it. Create a local variable, and
use that, example:
cfees2 NUMBER := cfees;
cfees2 := cfees2 - discount;
insert into STUDENTS values(rno, sname, cid, cfees2, spercent);
You don't need to define and calculate any local variables; you can do the computation of cfees in place (right in the INSERT statement):
create or replace procedure enrollstudent(
rno in STUDENTS.ROLL_NUMBER%type,
sname in STUDENTS.STUDENT_NAME%type,
cid in STUDENTS.COURSEID%type,
cfees in STUDENTS.FEES%type,
spercent in students.percentage%type
)as
begin
insert into STUDENTS values(rno, sname, cid, cfees-spercent*5, spercent);
commit;
end;
/
Is the character underscore ( '_' ) acceptable (insertable) in varchar2 type column?
There is a value that needs to be inserted into a varchar2 column of one of my tables, but the value contains an underscore, like 'DOC_OTHER'
The value does not get inserted into the varchar2 column, whereas other values which do not contain an underscore character in their values get easily inserted (as usual).
I'm unable to understand this unusual behavior. Suggest!!
Edit:
Since the value is being picked up from a web service response xml, this is how its done.
The sql code is fine. All other values are getting retrieved, plus there is nothing wrong with the path as well.
Looping through the response:
begin
for p in (
select * from
---- some xmlnamespaces of the response ----
columns
"DocData" varchar2(240) path 'path to DocData in response'
,"RepID" varchar2(200) path 'path to RepID in response'
,"DocInit" varchar2(400) path 'path to DocInit in response'
)
loop
begin
insert into pooling_info
(session_id, user_id, DocData, RepID, DocInit)
values(
p_session, p_user, p."DocData", p."RepID", p."DocInit"
);
end;
end loop;
end;
If the value of DocData does not contain an underscore character, it is inserted in the table, this is strange but if the data contains an underscore, the value is not inserted!
It does not throw any error. The surrounding values are inserted except for this (DocData) which contains an underscore
There is nothing out of the ordinary about adding an '_' character(s) to a VARCHAR2 column.
As others have pointed out, the '_' character is a wildcard so it does have a special meaning when used with a LIKE condition.
More than likely, I suspect the problem you are experiencing is either a size issue (e.g. you are trying to place something too large for the VARCHAR2 that you are modifying) or a constraint issue.
Here is an example of modifying a column using the example schema, SCOTT.
SCOTT#dev>
1 CREATE table EMP3 as
2 (SELECT *
3* FROM emp)
SCOTT#dev> /
Table created.
SCOTT#dev> select empno, ename from emp3 where empno = 7369;
EMPNO ENAME
========== ==========
7369 SMITH
1 row selected.
SCOTT#dev> DESC emp3;
Name Null? Type
-------------------------
EMPNO NOT NULL NUMBER (4)
ENAME VARCHAR 2(10)
JOB VARCHAR 2(9)
MGR NUMBER (4)
HIREDATE DATE
SAL NUMBER (7,2)
COMM NUMBER (7,2)
DEPTNO NUMBER (2)
SCOTT#dev> UPDATE emp3
2 SET ename = ename || '_BOB'
3 WHERE empno = 7369
4 ;
1 row updated.
SCOTT#dev> select ename
2 from
3 emp3 where empno = 7369;
ENAME
==========
SMITH_BOB
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.