SQL: Can't create function returning table. "Table is not valid at this position, expecting: bit, bool, boolean, ...." - sql

I can't figure out what's wrong with this SQL function... in "returns table" it complains that "Table is not valid at this position, expecting: bit, bool, boolean, ....". Does anyone know?
create table department(
dept_name varchar(20),
n_prof int,
budget numeric(10,2),
primary key (dept_name)
);
create table instructor(
ID char(5),
name varchar(20),
dept_name varchar(20),
salary numeric(8,2),
primary key (ID),
foreign key (dept_name) references department (dept_name)
);
create function instructors (dept_name char(20))
returns TABLE
as
return
select ID, name, dept_name, salary
from instructor
where instructor.dept_name=dept_name;

Based on error, I guess you are using MYSQL database.
As per documentation on user defined functions in MySQL
you can only return values of type {STRING|INTEGER|REAL|DECIMAL}
CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|INTEGER|REAL|DECIMAL}
SONAME shared_library_name
If you want to read a select resultset you have to define a procedure but not function.
DELIMITER //
DROP PROCEDURE IF EXISTS myProcedure //
CREATE PROCEDURE
myProcedure( dept_name char(20) )
BEGIN
select ID, name, dept_name, salary
from instructor
where instructor.dept_name=dept_name;
;
END
//
DELIMITER ;
And you can call procedure like
call myProcedure( 'CSE' )
That returns implicit objects based on the statements used in the procedure.

Please use below query.
USE Your_Database
create table dbo.department(
dept_name varchar(20),
n_prof int,
budget numeric(10,2),
primary key (dept_name)
);
GO
create table dbo.instructor(
ID char(5),
name varchar(20),
dept_name varchar(20),
salary numeric(8,2),
primary key (ID),
foreign key (dept_name) references department (dept_name)
);
GO
create function dbo.instructors (#dept_name char(20))
returns TABLE
as
return
select ID, name, dept_name, salary
from dbo.instructor
where instructor.dept_name=#dept_name;
You have used dept_name which is already existing in your table column so use #dept_name instead of that.
Please use GO statement to separate the each transaction otherwise you will get error.
Msg 111, Level 15, State 1, Line 19 'CREATE FUNCTION' must be the
first statement in a query batch. Msg 137, Level 15, State 2, Line 25
Must declare the scalar variable "#dept_name".

Related

Add constraint to SQL Server with condition

Consider this table
CREATE TABLE employee
(
employee_number INT PRIMARY KEY,
employee_name NVARCHAR(100),
employee_year INT,
manager_employee_number INT,
salary INT,
FOREIGN KEY(manager_employee_number)
REFERENCES employee(employee_number)
);
I want to add a constraint which every employee's employee_year is less than his manager's and we know every manager is an employee himself. So I wrote this:
ALTER TABLE employee
ADD CONSTRAINT CK_EmployeeYearLessThanManager
CHECK (employee_year <= (SELECT m.employee_year
FROM employee
WHERE m.employee_number = manager_employee_number ));
I get this error:
Subqueries are not allowed in this context. Only scalar expressions are allowed
Is there any possible way to write such a constraint?
As it can be seen from the error message, you cannot implement it as a subquery, but as a work around you can create a scalar-valued user defined function and call it from the check constraint. Here is an example:
CREATE TABLE employee
(
employee_number INT PRIMARY KEY,
employee_name NVARCHAR(100),
employee_year INT,
manager_employee_number INT,
salary INT,
FOREIGN KEY(manager_employee_number)
REFERENCES employee(employee_number)
);
GO
CREATE FUNCTION dbo.get_manager_hire_year(#manager_employee_number INT)
RETURNS INT
AS
BEGIN
DECLARE #e_year int;
SELECT #e_year = employee_year
FROM employee
WHERE employee_number = #manager_employee_number;
RETURN #e_year
END
GO
ALTER TABLE employee
ADD CONSTRAINT CK_EmployeeYearLessThanManager
CHECK (employee_year <= dbo.get_manager_hire_year(manager_employee_number))

"ORA-01733: virtual column not allowed here" when inserting into a view

I created a view called "view_employee" like this:
CREATE VIEW view_employee AS
SELECT employee.surname || ', ' || employee.name AS comp_name, employee.sex, sections.name AS section_name, employee_age
FROM sections, employee WHERE employee.section = sections.sect_code;
And I would like to insert data into the table using the view, like this:
INSERT INTO view_employee VALUES ('Doe, John', 'm', 'Marketing', 34);
Here are the tables' columns and constraints:
create table sections(
sect_code number(2),
name varchar2(20),
income number(5,2)
constraint CK_sections_income check (income>=0),
constraint PK_sections primary key (sect_code)
);
create table staff(
ident number(5),
document char(8),
sex char(1)
constraint CK_staff_sex check (sex in ('f','m')),
surname varchar2(20),
name varchar2(20),
address varchar2(30),
section number(2) not null,
age number(2)
constraint CK_staff_age check (age>=0),
marital_status char(10)
constraint CK_employee_marital_status check (marital_status in
('married','divorced','single','widower')),
joindate date,
constraint PK_employee primary key (ident),
constraint FK_employee_section
foreign key (section)
references sections(sect_code),
constraint UQ_staff_document
unique(document)
);
The error message I get when attempting to insert is the following:
Error starting at Command Line: 1 Column : 1
Error report -
SQL Error: ORA-01733: virtual column not allowed here
01733. 00000 - "virtual column not allowed here"
*Cause:
*Action:
How could I insert those values into the table using the view? Thanks in advance.
A view must not contain any of the following constructs. So, it can be updateable.
A set operator
A DISTINCT operator
An aggregate or analytic function
A GROUP BY, ORDER BY, MODEL, CONNECT BY, or START WITH clause
A collection expression in a SELECT list
A subquery in a SELECT list
A subquery designated WITH READ ONLY
Joins, with some exceptions, as documented in Oracle Database
Administrator's Guide.

Why is my PL/SQL trigger raising an "Error(2,2): PL/SQL: Statement ignored" and an "Error(2,5): PLS-00204: function or pseudo-column 'EXISTS' " error?

I am attempting to write a trigger which prevents the insertion into my TA (teaching assistant) table if the student is already taking the class for which they're attempting to become a TA. From what I understand the best way to do this (other than a unique constraint, this has to be a trigger) is through the use of rollback, and I'm also using raiserror.
create or replace trigger CheckTA
after insert
on TA for each row
begin
if exists (select * from Enrolls where Student_ID = :new.Student_ID and Course_ID = :new.Course_ID) then
rollback;
raiserror('TA enrolled in course as student');
end if;
end;
Upon creating the trigger, I'm met with the following errors:
Error(2,2): PL/SQL: Statement ignored
Error(2,5): PLS-00204: function or pseudo-column 'EXISTS' may be used inside a SQL statement only
The trigger still gets created, but it doesn't trigger when improper values are inserted into TA.
Tables:
TA
Create table TA
(
Student_ID int references Student(Student_ID),
Course_ID int references Course(Course_ID),
Courses_taught varchar2(250),
Office_hours varchar2(25)
);
Student
create table Student
(
Student_ID int primary key,
Name varchar2(50),
Start_began int,
Semester_began varchar2(50),
GPA int,
Degree_status varchar2(25),
Degree_type varchar2(50),
Courses_Taken varchar2(250),
JI_list varchar2(250),
Profile_status varchar2(50)
);
Course
create table Course
(
Course_ID int primary key,
Course_Name varchar2(25)
);
Enrolls
create table Enrolls
(
Student_ID int references Student(Student_ID),
Course_ID int references Course(Course_ID)
);
Stored Procedure
This is the SP I use to insert TA values that should trigger the trigger. It doesn't raise errors but I'll put it here in case it's relevant.
create or replace procedure addTA (s_id int, c_id int, course varchar2)
as
begin
insert into TA (Student_ID,Course_ID,Courses_taught)
values (s_id,c_id,course);
end;
Honestly I'm not quite sure what these errors mean, let alone what's causing them, but still I've tried messing with the syntax of raiserror as well as replacing it with raise_application_error with no luck. If anyone could help me resolve or at least explain these errors it would be greatly appreciated. And of course if there is anything obviously wrong with my trigger please let me know.
The error says "function or pseudo-column 'EXISTS' may be used inside a SQL statement only", meaning that you only can use EXISTS inside a SQL statment, while you are using in in a PL/SQL statement.
If you need to check for the existence of some records, you can try something like this:
vNum number;
...
select count(1)
into vNumber
from Enrolls
where Student_ID = ...
if vNumber > 0 then
...
else
...
end if;

ORA-00936: missing expression error when inserting values

I spend lot of time searching where i made the mistake but i was unable to find it when its going to insert the last record there is a error message showing "ORA-00936: missing expression" How to solve this please help me
create type pearson_types as object(
name varchar2(50),
sysID char(6)
)NOT FINAL;
create type doctor_types under pearson_types(
regNo char(10),
specialization varchar2(25)
)
create table doctor of doctor_types(
regNo primary key
)
create type hospVisits_types as object(
hosChg float,
vDate varchar2(20),
refDoc REF doctor_types,
docChg float
)
create type hospvisits_tbl_types as table of hospVisits_types
create type phone_arr as VARRAY(3) of char(10)
create type patient_types under pearson_types
(
id char(10),
dob varchar(20),
phone phone_arr,
hospVisits hospvisits_tbl_types
)
create table patients of patient_types(
id primary key
)nested table hospVisits store as Hospital_tables
alter table Hospital_tables add scope for (refDoc) is doctor
insert into doctor values ('Dr.k.perera','D001','1223441234','Gynecologist');
insert into doctor values ('Dr.p.weerasingha','D002','1234421131','Dermatalogist');
insert into doctor values ('Prof .S. Fernando','D003','2342111322','Pediatrician');
insert into doctor values ('Dr.k.Sathgunanathan','D004','2344114344','Pediatrician');
insert into patients values('Sampath Weerasingha','P001','732821122V','23-JAN-73',phone_arr('0332124222'),hospvisits_tbl_types(hospVisits_types(50.00,'24-MAY-06',select ref (a) from doctor a where a.regNo='1223441234',500.00)))
Add parentheses to SELECT statements inside a SQL statement:
insert into patients values(
'Sampath Weerasingha','P001','732821122V','23-JAN-73',phone_arr('0332124222'),
hospvisits_tbl_types(hospVisits_types(50.00,'24-MAY-06',
( -- ADD ME
select ref (a) from doctor a where a.regNo='1223441234'
) -- ADD ME
,500.00))
);

Unable to create trigger in Oracle/iSQL

I made a table student, in which there is an attribute evaluation.
Now i am making a trigger in which i want that if i insert a value of zero in evaluation then a trigger should fire and store some values in audit_table.
here is my code
Create table Student ( Student_Id Number(8,2), Student_Name Varchar2(50), Gender Varchar(8), Telephone_No Number(15), Location Varchar2(200), Education Varchar2(100), Company_name Varchar2(200), No_of_attempt Number(2), Offering_Id Number(3) , EVALUATION NUMBER(2), Primary Key (Student_Id), Constraint fk_Oid Foreign Key (Offering_Id) References Course(Offering_Id) );
And now the audit table code
CREATE TABLE AUDIT_TABLE ( STUD_NAME VARCHAR2(100), COURSE_NAME
VARCHAR2(100), INSTRUCTOR_NAME VARCHAR2(200), EVALUATION NUMBER (2)
);
Now my main question is this my trigger not working
create trigger tr_student
after insert or update on student
for each row
declare
s_name student.student_name%type;
s_eval student.evaluation%type;
s_offr_id student.offering_id%type;
s_course_name student.student_name%type;
s_instr student.student_name%type;
begin
if evaluation == 0;
s_offr_id =(select offering_id from student where evaluation==0);
s_eval =0;
s_name =(select student_name from student where evaluation==0);
s_course_name =(select course_name from course where offering_id==s_offr_id);
s_instr=(select name from instructor where offering_id==s_offr_id);
insert into AUDIT_TABLE values(s_name,s_course,s_instr,s_eval);
end;
Is there some problem with my trigger?
This is not possible:
s_name =(select student_name from student where evaluation==0);
Change it to
select student_name into s_name from student where evaluation = 0;
Note there are two problems. First, you need into to select a value into a variable. Second, the comparison operator in SQL is only a single =.
The same goes for
if evaluation == 0;
..
end;
It should be
if :new.evaluation = 0 then
...
end if;
So there, the you forgot the then and end if, the comparison operator is wrong and you need :new.fieldname to get the value of the field, instead of a local variable.
The assignment operator in PLSQL is :=, so
s_eval =0;
should be changed to
s_eval := 0;
It seems you need to grab the schoolbook again and do some more reading. :)