i have the following code for table value Function in oracle 12c on windows8
as following
CREATE TABLE MisJob
( ID RAW(16),
JobTitle VARCHAR2(35 BYTE),
MinSalary NUMBER(6,0),
MaxSalary NUMBER(6,0),
PRIMARY KEY (ID)
)
CREATE TYPE MISJOBType AS OBJECT ( JobTitle VARCHAR2(35 BYTE), MinSalary NUMBER(6,0),MaxSalary NUMBER(6,0));
CREATE TYPE MISJOBTypeCol AS TABLE OF MISJOBType;
CREATE OR REPLACE FUNCTION fEmployee (jobid IN RAW(16))
RETURN MISJOBTypeCol PIPELINED IS
BEGIN
FOR i IN (SELECT * FROM MisJob)LOOP
PIPE ROW(MISJOBType(i.JobTitle, i.MinSalary,i.MaxSalary));
END LOOP;
RETURN;
END;
but i am getting the error
Error(2,13): PLS-00103: Encountered the symbol "(" when expecting one of the following: := . ) , # % default character The symbol ":=" was substituted for "(" to continue.
and i don't know why even though i have followed this example
Table-Valued Functions in ORACLE 11g ? ( parameterized views )
what is wrong
Remove the size constraint on the formal argument:
CREATE OR REPLACE FUNCTION fEmployee (jobid IN RAW)
...
From the documentation:
... you cannot include a constraint in a formal parameter declaration
Related
I'm trying to compile this procedure. I whish it gets table row as parameter:
create or replace PROCEDURE MY_HELPER (rep_table_row IN OUT rep_table_T%ROWTYPE) IS
...
END MY_HELPER ;
The table is defined as
create or replace TYPE "rep_table_T" AS TABLE OF rep_table_O;
The object is defined as:
create or replace TYPE "rep_table_O" AS OBJECT (
"day" VARCHAR2(250 BYTE),
"TS" DATE
);
However I can't compile it because I'm getting the error:
PLS-00201 identifier "rep_table_T" must be declared.
Remove the %ROWTYPE. That only applies to actual sql tables, not pl/sql collections. From the documentation, "The %ROWTYPE attribute provides a record type that represents a row in a database table. "
Yeah it is very confusing as a new user that oracle calls actual tables and pl/sql tables the same thing.
Forget about double quotes while in Oracle. If you use them while creating any objects, you have to use them always.
As of your code: removed double quotes, removed rowtype in procedure declaration.
SQL> CREATE OR REPLACE TYPE rep_table_o AS OBJECT
2 (
3 day VARCHAR2 (250 BYTE),
4 ts DATE
5 );
6 /
Type created.
SQL> CREATE OR REPLACE TYPE rep_table_t AS TABLE OF rep_table_o;
2 /
Type created.
SQL> CREATE OR REPLACE PROCEDURE my_helper (
2 rep_table_row IN OUT rep_table_t)
3 IS
4 BEGIN
5 NULL;
6 END my_helper;
7 /
Procedure created.
SQL>
You have two errors:
Do not use quoted identifiers:
CREATE TYPE rep_table_O AS OBJECT (
day VARCHAR2(250 BYTE),
TS DATE
);
CREATE TYPE rep_table_T AS TABLE OF rep_table_O;
(Or, if you really must have lower-case identifiers [why?] then you need to use quoted identifiers, with exactly the same case, everywhere that identifier is used.)
Do not use %ROWTYPE:
CREATE PROCEDURE MY_HELPER (
rep_table_row IN OUT rep_table_T
)
IS
...
END MY_HELPER;
db<>fiddle here
Question is : Function: Create a Function named 'find_credit_card' which takes card_no as input and returns the holder name of type varchar.
Function name: find_credit_card
Input Parameter: card_no with data type as varchar
Output variable : holder_name with data type as varchar(30)
Hint: Add '/' after the end statement
Refer to the schema.
My code :-
CREATE OR REPLACE FUNCTION find_credit_card(card_no IN VARCHAR2(255))
RETURN VARCHAR
IS
holder_name VARCHAR(255)
BEGIN
SELECT name
INTO holder_name
from credit_card
where card_number = card_no;
RETURN(holder_name);
END;
/
Warning : Function created with compilation errors.
Error(s) you got can be reviewed in SQL*Plus by running show err:
Warning: Function created with compilation errors.
SQL> show err
Errors for FUNCTION FIND_CREDIT_CARD:
LINE/COL ERROR
-------- -----------------------------------------------------------------
1/46 PLS-00103: Encountered the symbol "(" when expecting one of the
following:
:= . ) , # % default character
The symbol ":=" was substituted for "(" to continue.
5/1 PLS-00103: Encountered the symbol "BEGIN" when expecting one of
the following:
:= ; not null default character
SQL>
Alternatively, query user_errors:
select line, position, text
from user_errors
where name = 'FIND_CREDIT_CARD';
Oracle says that there are two errors:
first one means that function's parameter shouldn't have size, so - not card_no in varchar2(255) but only card_no in varchar2
another one means that you forgot to terminate line where local variable was declared (missing semi-colon at the end of that line):
holder_name VARCHAR(255);
However, consider inheriting datatype from column description. If it is ever changed, you wouldn't have to modify your code.
Furthermore, it would be good if you distinguish parameters and local variables from column names. How? Use prefixes, e.g. par_ for parameters, l_ or v_ for local variables.
Also, Oracle recommends us to use varchar2, not varchar.
Finally, that function might look like this:
SQL> CREATE OR REPLACE FUNCTION find_credit_card
2 (par_card_number IN credit_card.card_number%TYPE)
3 RETURN credit_card.name%type
4 IS
5 l_holder_name credit_card.name%TYPE;
6 BEGIN
7 SELECT name
8 INTO l_holder_name
9 FROM credit_card
10 WHERE card_number = par_card_number;
11
12 RETURN l_holder_name;
13 END;
14 /
Function created.
SQL> select find_credit_card('HR123456789') holder from dual;
HOLDER
---------------------------------------------------------------------
Littlefoot
SQL>
I am using Oracle database 19c for a project. I have created the alumni table as shown below:
CREATE TABLE Alumni (
ID NUMBER GENERATED ALWAYS AS IDENTITY ,
First_Name varchar2(20) NOT NULL,
Last_Name varchar2(20) NOT NULL,
Gender char(1) NOT NULL,
CHECK (Gender IN('M','F')),
Graduation_Year number NOT NULL,
check (Graduation_Year>=1980 AND Graduation_Year<=2020),
Degree_Course varchar2(255) not null,
Award_Nominated CHAR(1),
CHECK (Award_Nominated IN('Y','N')),
Award_Won CHAR(1),
CHECK (Award_Won IN('Y','N')),
Phone_Number VARCHAR2(15) not null,
Email_Address VARCHAR2(255) not null,
CONSTRAINT ALUM_PK PRIMARY KEY(ID)
);
Then I tried to define a function that will allow me to search by First or last name in a section of the table, shown below:
CREATE OR REPLACE TYPE alum_row_type is object(ID number,First_name varchar2(20),Last_Name
varchar2(20),Phone_number varchar2(15),Email_Address varchar2(255));
CREATE OR REPLACE TYPE t_alum_row_type as table of alum_row_type;
CREATE OR REPLACE FUNCTION Name_Search RETURN t_alum_row_type
IS
L_alum_row t_alum_row_type := t_alum_row_type();
X integer :=0;
BEGIN
FOR R IN (SELECT ID,First_Name, Last_Name,Phone_Number,Email_Address FROM alumni)
LOOP
L_alum_row.extend;
X:=X+1;
L_alum_row(X):= alum_row_type(X.ID,X.First_Name, X.Last_Name, X.Phone_Number, X.Email_Address);
END LOOP;
RETURN L_alum_row;
END;
After running this, I get this error:
LINE/COL ERROR
--------- -------------------------------------------------------------
10/9 PL/SQL: Statement ignored
10/41 PLS-00487: Invalid reference to variable 'X'
Errors: check compiler log
How can I resolve this issue. I am relatively new to PL\SQL, so please explain it simply.
This is not possible
L_alum_row(X):= alum_row_type(X.ID,X.First_Name, X.Last_Name, X.Phone_Number, X.Email_Address);
You are referencing X.ID, X.Phone_Number etc. . . but declared X as an integer. If you are trying to access the current loop record, try with
L_alum_row(X):= alum_row_type(R.ID,R.First_Name, R.Last_Name, R.Phone_Number, R.Email_Address);
As you declared the loop iterator as R for your cursor
FOR R IN (SELECT ID,First_Name, Last_Name,Phone_Number,Email_Address FROM alumni)
You can eliminate the loop altogether by using BULK COLLECT. Thereby reducing the function to basically a single select statement.
function name_search
return t_alum_row_type
is
l_alum_row t_alum_row_type := t_alum_row_type();
begin
select alum_row_type(id,first_name, last_name,phone_number,email_address)
bulk collect
into l_alum_row
from alumni;
return l_alum_row;
end;
I have this dummy types :
create or replace type Service_TY as object(
code INTEGER,
visit_analysis char(1)
)FINAL;
/
create or replace type Employee_TY as object(
dummy varchar(30)
)NOT FINAL;
/
create or replace type Doctor_TY UNDER Employee_TY(
ID INTEGER
)FINAL;
/
create or replace type Assistant_TY UNDER Employee_TY(
ID INTEGER
)FINAL;
/
create or replace type Habilitation_TY as object(
employee ref Employee_TY,
service ref Service_TY
)FINAL;
/
And these dummy tables:
CREATE TABLE Service of Service_TY(
code primary key,
visit_analysis not null check (visit_analysis in ('v', 'a'))
);
/
CREATE TABLE Doctor of Doctor_TY(
ID primary key
);
/
CREATE TABLE Assistant of Assistant_TY(
ID primary key
);
/
CREATE TABLE Habilitation of Habilitation_TY;
/
I want to create a trigger that, when a new tuple is inserted in Habilitation, should check that, if the employee is an assistant (and not a doctor), the visit_analysis attribute is equal to 'a' to know if it is a legal tuple.
I don't know how to check the type of the Employee (if it is a doctor or an assistant).
I would do something like that:
create or replace
TRIGGER CHECK_HABILITATION
BEFORE INSERT ON HABILITATION
FOR EACH ROW
DECLARE
BEGIN
IF (:NEW.EMPLOYEE is of ASSISTANT_TY)
THEN
IF :NEW.SERVICE.visit_analysis = 'v'
THEN
raise_application_error(-10000, 'invalid tuple');
END IF;
END;
But it's not working.
How should I check that type?
The error I get is:
Error(14,4): PLS-00103: Encountered the symbol ";" when expecting one of the following: if
Try to put it into a variable, the following one should work.
create or replace
TRIGGER CHECK_HABILITATION
BEFORE INSERT ON HABILITATION
FOR EACH ROW
DECLARE
emp employee_TY;
ser service_TY;
BEGIN
select deref(:new.employee) into emp from dual;
if (emp is of (assistant_ty)) then
select deref(:new.service) into ser from dual;
if ser.visit_analysis = 'v' then
raise_application_error('-20001', 'invalid tuple');
end if;
end if;
END;
/
According to the documentation for the IS OF condition, you need to wrap the type in parentheses, like:
IF (:NEW.EMPLOYEE is of (ASSISTANT_TY) )
per https://docs.oracle.com/cd/B28359_01/server.111/b28286/conditions014.htm#SQLRF52157.
I'm not really familiar with using object types so there may be some other issue that I'm not seeing.
There is a similar answer for the problem I have, but it seems that this answer is for procedure issue.
I supposed to make a pl sql package which has 3 procedures inside. It's gonna be like that:
CREATE OR REPLACE PACKAGE Count_num AS
PROCEDURE count_emps(dno IN number);
PROCEDURE count_deps(empssn IN char(9));
PROCEDURE delete_deps(empssn IN char(9), dname IN varchar2(15));
END;
/
show errors
CREATE OR REPLACE PACKAGE BODY Count_num AS
PROCEDURE count_emps(dno IN number)
AS
cnt number;
BEGIN
SELECT COUNT(*) INTO cnt
WHERE Department.dnumber = Employee.dno
AND Department.dnumber = dno;
dbms_output.put_line('Number of Employee is ' || cnt);
END;
PROCEDURE count_deps(empssn IN char(9))
AS
cnt2 number;
BEGIN
SELECT COUNT(*) INTO cnt2
WHERE Dependent.essn = Employee.ssn
AND Department.essn = empssn;
dbms_output.put_line('Number of dependent is ' || cnt2);
END;
PROCEDURE delete_deps(empssn IN char(9), dname IN varchar2(15))
AS
BEGIN
DELETE *
FROM Dependent
WHERE Dependent.essn = Employee.ssn
AND Dependent.essn = empssn
AND Dependent.dependent_name = dname;
SELECT *
FROM Dependent
WHERE Dependent.essn = Employee.ssn
AND Dependent.essn = empssn
AND Dependent.dependent_name = dname;
END;
END;
/
show errors
EXEC Count_num.count_emps(5);
EXEC Count_num.count_deps('333445555');
EXEC Count_num.delete_deps('333445555', 'Alice')
show errors
count_emps counts the number of employees for a department,
count_deps counts the number of dependents for a valid employee,
delete_deps deletes a specific depdendent. It's creation query is like below:
drop table Employee cascade constraints;
commit;
create table Employee
(
fname varchar2(15),
minit varchar2(1), -- can be char
lname varchar2(15),
ssn char(9),
bdate date,
address varchar2(50),
sex varchar2(1) CHECK(Sex = 'M' or Sex = 'F'),
salary number, -- need to put check on salary
superssn char(9),
dno number DEFAULT 0,
constraint EMPPK
primary key(ssn),
constraint EMPSUPERVRFK
foreign key(superssn) references Employee(ssn)
ON DELETE SET NULL
);
drop table Department cascade constraints;
commit;
create table Department
(
dname varchar2(15) NOT NULL,
dnumber number,
mgr_ssn char(9) DEFAULT '000000000',
mgr_start_date date,
constraint DEPTPK
primary key(dnumber),
constraint DEPTMGRFK
foreign key(mgr_ssn) references Employee(ssn)
ON DELETE SET NULL
);
drop table Dependent cascade constraints;
commit;
create table Dependent
(
Essn char(9),
Dependent_name varchar2(15),
Sex varchar2(15),
Bdate date,
Relationship varchar2(15),
constraint DEPENDPK
primary key (Essn, Dependent_name),
constraint DEPENDFK
foreign key(Essn) references Employee(Ssn)
);
When I execute package queries, it gives me an error like below:
SQL> CREATE OR REPLACE PACKAGE Count_num AS
2 PROCEDURE count_emps(dno IN number);
3 PROCEDURE count_deps(empssn IN char(9));
4 PROCEDURE delete_deps(empssn IN char(9), dname IN varchar2(15));
5 END;
6 /
Warning: Package created with compilation errors.
Elapsed: 00:00:00.02
SQL> show errors
Errors for PACKAGE COUNT_NUM:
LINE/COL ERROR
-------- -----------------------------------------------------------------
3/37 PLS-00103: Encountered the symbol "(" when expecting one of the
following:
:= ) , default varying character large
The symbol ":=" was substituted for "(" to continue.
4/38 PLS-00103: Encountered the symbol "(" when expecting one of the
following:
:= ) , default varying character large
The symbol ":=" was substituted for "(" to continue.
4/60 PLS-00103: Encountered the symbol "(" when expecting one of the
LINE/COL ERROR
-------- -----------------------------------------------------------------
following:
:= . ) , # % default character
The symbol ":=" was substituted for "(" to continue.
I can't recognize what this error is, so anyone can explain what this error is, and how can I handle this issue?
Remove the length specified for the data types in the arguments.
Also, better to specify the column data type than hard-coding it.
CREATE OR REPLACE PACKAGE Count_num AS
PROCEDURE count_emps(i_dno IN employee.dno%TYPE);
PROCEDURE count_deps(i_empssn IN employee.ssn%TYPE);
PROCEDURE delete_deps(i_empssn IN employee.ssn%TYPE,
i_dname IN department.dname%TYPE
);
END;
/