Adding constraints to an SQL Table with altering - sql

I have a defined type:
CREATE TYPE salary AS (salary numeric);
and a table holding data:
CREATE TABLE employees (
lastname text,
firstname text,
salary salary,
);
I want to use ALTER TABLEto add a constraint to the salary attribute:
ALTER TABLE employees ADD CONSTRAINT minimum_salary CHECK(salary > 1.47333);
this gives me the error ERROR: operator does not exist: salary > numeric. Why is this the case?

To start with: a type seems overkill to just store a scalar value. Why no just create a check constraint on the column?
create table employees (
lastname text,
firstname text,
salary numeric check(salary > 1.473333)
);
Coming back to your original question: I don't think that it is possible to put a check constraint on a type column. One thing you could do, however, is to create a domain. Domains extend the standard types and do accept check constraints.
Consider this demo:
create domain salary numeric check(value > 1.47333);
create table employees (lastname text, firstname text, salary salary);
insert into employees values('foo', 'bar', 1);
-- ERROR: value for domain salary violates check constraint "salary_check"

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))

How to make an employee wage restriction?

I have a database with an employee table. This table has the attributes:
name, id, adress and salary.
I need to restrict the salary of employees between US $ 5000 to US $ 10,000. How can I implement this restriction?
My attempt was to define the data type of the salary attribute as:
NUMERIC (5000, 10000)
However when I went to search the sql documentation I saw that NUMERIC (p, s) means
p: precision
s: scale
Try the check constraint when you create the table:
salary NUMERIC
CONSTRAINT salary_range
CHECK(salary >= 5000 and salary <= 10000)
Use Check constraint while creating the table.
create table (
name,
id,
adress,
salary check (salary between ( 5000 and 10,000))

Error on CHECK constraint in HANA SQL

I'm trying to create a table in the SQL Console of the catalog editor on a HANA SPS12 system with this statement:
create table testEmployee (
empid varchar(4) primary key,
salary number(6),
CHECK (salary >= 50000 and salary <= 200000)
)
It works if I change the CHECK into two separate statements but when I use the statement with the and I get this error:
12:25:20 PM (SQL Editor) Could not execute 'create table testEmployee ( empid varchar(4) primary key, salary number(6), CHECK ...'Error: (dberror) 288 - cannot use duplicate table name: TESTEMPLOYEE: line 2 col 13 (at pos 13)
Any suggestions?
Thanks,
Ross
This seems to be a wrong error message (aka bug) to me.
The problem does not occur when stating the check condition like this:
create table testEmployee (
empid varchar(4) primary key,
salary number(6),
CHECK (salary between 50000 and 200000)
);
In my tests it seemed to me that
A) one can create multiple check constraints by running multiple ALTER TABLE ADD CHECK commands, like so:
create table checker (
empid varchar(4) primary key,
salary number(6)
);
alter table checker add CHECK ( salary + empid > 100);
alter table checker add CHECK ( mod(salary/empid, 2)= 1);
alter table checker add CHECK ( salary between 1000 and 50000);
B) every single CHECK CONSTRAINT can appear on reference each column once. So, SALARY BETWEEN 5000 and 200000 works, while the logical equivalent SALARY >= 5000 and SALARY <= 200000 results in the error message.
UPDATE: the problem with the wrong error message does not occur on HANA 2SP02 and newer.

"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.

alter table for scope

This is the code I found on a course
create type employee_type AS OBJECT
( empno number(4),
ename varchar2(40),
dept_ref REF department_type)
/
create table employee of employee_type
( empno PRIMARY KEY )
/
create type department_type AS OBJECT
( deptno number(2),
dname varchar2(20),
loc varchar(20))
/
create table employee of employee_type
( empno PRIMARY KEY )
/
create table department of department_type
( deptno PRIMARY KEY )
/
alter table employee
add (scope for (dept_ref) is department)
/
I don't understand why we need to alter employee table to add scope for to department table, I mean dept_ref has been referred to department_type already and department table is consisted of department_type object, what is the add scope statment do?
As described in the documentation, the purpose is to say that dept_ref in employee has to refer, specifically, to a department, and not to any other table that may be of department_type type.
See REF Columns: Examples:
The dept column can store references to objects of dept_t stored in any table. If you would like to restrict the references to point only to objects stored in the departments table, then you could do so by adding a scope constraint on the dept column as follows ...
(People, apparently, love drawing examples from the domain of employees and departments)