How to create a constraint that allows 2 options using SQL Server? - sql

Could anyone help saying how I could create a constraint that allows 2 options using SQL Server?
For exapmle, I want it to be possible to add new candidates only if they have an intermediate or advanced knowledge in SQL.
So, I coded like below, but it doesn’t work.
CREATE TABLE Candidates
(
Name VARCHAR(150) NOT NULL UNIQUE,
BirthDate DATE NOT NULL,
SQLlevel VARCHAR(100) NOT NULL
CHECK (SQLlevel = 'Intermediate' OR 'Advanced')
)
Thanks in advance.

You can use in:
CREATE TABLE Candidates (
Name VARCHAR(150) NOT NULL UNIQUE,
BirthDate DATE NOT NULL,
SQLlevel VARCHAR (100) NOT NULL,
CHECK (SQLlevel IN ('Intermediate', 'Advanced'))
)

To explain why what you had didn't work it's because of your boolean expression:
SQLlevel = 'Intermediate' OR 'Advanced'
Your expression after the OR isn't a boolean expression, it's just a literal. You have to define the comparison operator each time. If you wanted to use a OR you would need to do the following:
CREATE TABLE Candidates (Name varchar(150) NOT NULL UNIQUE,
BirthDate date NOT NULL,
SQLlevel varchar(100) NOT NULL CHECK (SQLlevel = 'Intermediate' OR SQLlevel = 'Advanced'));

You're missing the word CONSTRAINT and a name
CREATE TABLE Candidates
(
Name VARCHAR(150) NOT NULL UNIQUE,
BirthDate DATE NOT NULL,
SQLlevel VARCHAR(100) NOT NULL,
constraint chck_candidates_levels
CHECK (SQLlevel in('Intermediate', 'Advanced'))
);

Related

Postgresql generated column fails when concating not null columns

I have this table definition in pgAdmin4:
CREATE TABLE IF NOT EXISTS cdr_event
(
id bigint primary key generated always as identity,
start_time timestamptz NOT NULL DEFAULT now(),
end_time timestamptz NULL,
group_id VARCHAR(10) NOT NULL,
environment VARCHAR(10) NOT NULL,
level VARCHAR(10) NOT NULL,
schema VARCHAR(30) NOT NULL,
instance INTEGER NOT NULL,
hive_instance_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema||'_'||instance) STORED,
hive_static_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema) STORED,
);
this fails with
ERROR: generation expression is not immutable
SQL state: 42P17
Why does postgres consider the concat mutable when the dependent columns are all NOT NULL? This thread suggests it should work
Is there anyway to create a concat-ed generated column without creating a custom concat function?
Thanks
Try keeping the involved columns of the same type, e.g. casting instance to text should do the trick:
CREATE TABLE IF NOT EXISTS cdr_event
(
id bigint primary key generated always as identity,
start_time timestamptz NOT NULL DEFAULT now(),
end_time timestamptz NULL,
group_id VARCHAR(10) NOT NULL,
environment VARCHAR(10) NOT NULL,
level VARCHAR(10) NOT NULL,
schema VARCHAR(30) NOT NULL,
instance INTEGER NOT NULL,
hive_instance_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema||'_'||instance::text) STORED,
hive_static_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema) STORED
);
Consider using text instead of varchar.
Demo: db<>fiddle

Set some field 'NOT NULL' only if a field has a special value

CREATE TABLE Persona(
CF VARCHAR(16) PRIMARY KEY,
Nome VARCHAR(50) NOT NULL,
Cognome VARCHAR(50) NOT NULL,
Email VARCHAR(50) NOT NULL,
RuoloPersona VARCHAR(20) NOT NULL CHECK(RuoloPersona IN ('Studente', 'Professore', 'Tutor', 'Ex-Studente')),
Telefono NUMERIC(10) NOT NULL,
Scuola NUMERIC(5) NOT NULL REFERENCES Scuola ON UPDATE CASCADE ON DELETE RESTRICT,
Genere VARCHAR(50),
Ruolo VARCHAR(50),
Materia VARCHAR(50) DEFAULT NULL,
Classe VARCHAR(5) DEFAULT NULL,
Sezione VARCHAR(5) DEFAULT NULL,
Note VARCHAR(100),
CHECK((RuoloPersona='Professore' AND Materia!=NULL) OR (RuoloPersona!='Professore' AND Materia=NULL)),
CHECK((RuoloPersona='Studente' AND Classe!=NULL) OR (RuoloPersona!='Studente' AND Classe=NULL)),
CHECK((RuoloPersona='Studente' AND Sezione!=NULL) OR (RuoloPersona!='Studente' AND Sezione=NULL)));
I am trying to create a table Person that can contain students and teachers too. To make this possible, i've created a field called 'RuoloPersona', that mark if a person is a student or a teacher. I want the field 'Materia' to be NON NULL when a teacher is added and i want the fields 'Classe' and 'Sezione' to be NON NULL when a student is added, in all other cases i want them to be NULL. Obviously what i've written above doesn't work, but explains my idea.
The correct way to express the check constraints is:
CHECK ( (RuoloPersona = 'Professore' AND Materia IS NOT NULL) OR
(RuoloPersona <> 'Professore' AND Materia IS NULL)
),
CHECK( (RuoloPersona = 'Studente' AND Classe IS NOT NULL AND Sezione IS NOT NULL) OR
(RuoloPersona <> 'Studente' AND Classe IS NULL AND Sezione IS NULL)
)
This uses the standard SQL operator <> for "not equals". For NULL comparisons, you should always use IS NULL and IS NOT NULL.

Create Table - Time Statement

I am having trouble trying to create a table using MS Access.
I know for sure my problem lies in the "datetime" field but I can not figure what I am missing or doing wrong.
When I click "run" I get the
"Syntax Error in Field Definition"
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
Day varchar(8) not null,
Time datetime not null,
Procedure varchar(50) null);
Time and procedure are reserved words, and therefore should be escaped:
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
[Day] varchar(8) not null,
[Time] datetime not null,
[Procedure] varchar(50) null);
Or better yet, find names that aren't reserved words:
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
AppointmentDay varchar(8) not null,
AppointmentTime datetime not null,
MedicalProcedure varchar(50) null);
Here Procedure and Time are reserved words and so need to be escaped using [] like below. See Documentation for more information
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
[Day] varchar(8) not null,
[Time] datetime not null,
[Procedure] varchar(50) null);
As Time & Procedure are reserved keyword, so wrap Time & Procedure column in brackets [] or choose alternate names, if possible. See List of Keyword
[Time] and [Procedure]

How to define table constraint to check non empty datetime?

While creating a table how to add table level constraint so as to check that a column with datatype datetime is not empty?
You would use something like this with NOT NULL:
CREATE TABLE [dbo].[MyTable](
[ID] [int] NOT NULL,
[MyField] [DATETIME] NOT NULL)
The NOT NULL constraint enforces a column to NOT accept NULL values.
The NOT NULL constraint enforces a field to always contain a value. This means that you cannot insert a new record, or update a record without adding a value to this field.
The following SQL enforces the "P_Id" column and the "LastName" column to not accept NULL values:
CREATE TABLE PersonsNotNull
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
If the date field has a point beyond which you know there will be no valid dates, you can set that as a lower boundary.
Date_Field date check( Date_Field > '2000-01-01' ),
If it is peoples birthdate, you will have to set it back to a more reasonable value. Now, now matter how the date is entered or what is is converted from, it must be within a reasonable range to be considered valid.

SQL server 2012 tables issue, sysdate and to_date issue

I have two issues while trying to create tables.
For **sysdate*** it says invalid column name
for *TO_DATE('01-JAN-2008','DD-MON-YYYY')));* it says TO_DATE is not a reconigized built-in function name.
^ both are in the Table Invoice.
This is using SQL SERVER 2012
CREATE TABLE VENDOR(
V_CODE INTEGER NOT NULL UNIQUE,
V_NAME VARCHAR(35) NOT NULL,
V_CONTACT VARCHAR(15) NOT NULL,
V_AREACODE CHAR(3) NOT NULL,
V_PHONE CHAR(8) NOT NULL,
V_STATE CHAR(2) NOT NULL,
v_ORDER CHAR(1) NOT NULL,
PRIMARY KEY (V_CODE));
CREATE TABLE PRODUCT(
P_CODE VARCHAR(10) NOT NULL,
P_DESCRIPT VARCHAR(35) NOT NULL,
P_INDATE DATE NOT NULL,
P_QOH SMALLINT NOT NULL,
P_MIN SMALLINT NOT NULL,
P_PRICE DECIMAL(8,2) NOT NULL,
P_DISCOUNT DECIMAL(5,2) NOT NULL,
V_CODE INTEGER,
PRIMARY KEY (P_CODE),
FOREIGN KEY(V_CODE) REFERENCES VENDOR ON UPDATE CASCADE);
CREATE TABLE CUSTOMER(
CUS_CODE DECIMAL PRIMARY KEY,
CUS_LNAME VARCHAR(15) NOT NULL,
CUS_FNAME VARCHAR(15) NOT NULL,
CUS_INITIAL CHAR(1),
CUS_AREACODE CHAR(3) DEFAULT '615' NOT NULL,
CHECK(CUS_AREACODE IN ('615','713','931')),
CUS_PHONE CHAR(8) NOT NULL,
CUS_BALANCE DECIMAL(9,2) DEFAULT 0.00,
CONSTRAINT CUS_UI1 UNIQUE (CUS_LNAME, CUS_FNAME));
CREATE TABLE INVOICE (
INV_NUMBER DECIMAL PRIMARY KEY,
CUS_CODE DECIMAL NOT NULL REFERENCES CUSTOMER(CUS_CODE),
INV_DATE DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT INV_CK1 CHECK (INV_DATE > TO_DATE('01-JAN-2008','DD-MON-YYYY')));
You have two issues:
the function to get the current system date and time is called SYSDATETIME() in T-SQL/SQL Server (not sysdate)
the way to convert a string to a date or datetime in T-SQL/SQL Server is using CAST or CONVERT (not TO_DATE - there is no such function in T-SQL)
Use something like
SELECT CAST('01-JAN-2008' AS DATE)
or something like that (it's highly dependent on your language/date format settings in SQL Server whether it'll work or not). If you need to specify a specific format, you can use CONVERT which allows you to use one of the many predefined formats (see relevant details in the MSDN documentation).
If that's still not enough - SQL Server 2012 has a new function called PARSE which allows you to specify any arbitrary date format that your string is formatted in. Again, see the relevant MSDN documentation for details.
The best thing is to avoid converting dates back and forth to and from strings if ever possible, and in your case, this should be easily doable! Just use:
INV_DATE DATE DEFAULT SYSDATETIME() NOT NULL,
CONSTRAINT INV_CK1 CHECK (INV_DATE > '20080101');