Use a condition while creating a table in SQL - sql

I'd like to create a table with a condition
create table TOTO
(
Id int not null,
zip as (if(zip > '00999' and zip < '96000') then zip) ,
PRIMARY KEY (Id)
);
All I get is an error message.
Do you know how to do that with the "zip" in type char ?
Thank you for your help !

You may want to use CHECK constraint instead
CREATE TABLE TOTO
(
Id int NOT NULL,
zip char,
PRIMARY KEY (Id),
CHECK (zip > '00999' AND zip < '96000')
);

You can get this done either using a CHECK CONSTRAINT or using a BEFORE INSERT or INSTEAD OF trigger
An example:
CREATE TRIGGER ChkZip
ON TOTO
INSTEAD OF INSERT
AS
BEGIN
IF (inserted.zip > '00999' and inserted.zip < '96000')
BEGIN
INSERT INTO TOTO (id,zip) VALUES (insered.id, inserted.zip)
END
ELSE
BEGIN
RAISERROR ('The entered zip code doesn't match criteria.' ,10,1)
ROLLBACK TRANSACTION
END
END

CREATE TABLE TOTO
(
Id INT NOT NULL,
zip VARCHAR2(10),
PRIMARY KEY (Id),
CONSTRAINT CHK_zip CHECK (zip > to_number('00999') AND zip < to_number('96000'))
);
You could use check constraint - the above script is based on Oracle Sql function

You need to create a new CHECK constraint so that your field is guaranteed to comply with this constraint each time it is set or modified (insert or update).
Here is an example adapted to SQL server (as you seem to be using that dbms) where the constraint is named so you can identify it more easily (better for maintainability)
create table TOTO
(
Id int not null,
zip char ,
PRIMARY KEY (Id),
CONSTRAINT CHK_zip CHECK(zip > '00999' and zip < '96000')
);
Note that you could formulate it using patterns as in the link I provided.

Related

How to fix the trigger with check compiler log error?

Please, help!
I have trigger:
CREATE TRIGGER check_reservation BEFORE INSERT ON order
FOR EACH ROW
DECLARE mistake INTEGER;
BEGIN
SELECT count(*) INTO mistake FROM order join reserving
on id_order = reserving.order_id_order
WHERE reserving.room_num_room=:new.room_num_room
AND (order.reservation_from < :new.reservation_from AND :new.reservation_from < order.reservation_to) OR
(order.reservation_from < :new.reservation_from AND :new.reservation_to < order.reservation_to) OR
(:new.reservation_from <= order.reservation_from AND order.reservation_to <= :new.reservation_to);
IF mistake>0 THEN
raise_application_error(-20001,'reservation already exists');
END IF;
END;
The idea of the trigger is not to allow make a reservation on already booked room. When I run it I had check compiler log error message. How can I change trigger?
I have following tables:
CREATE TABLE order (
id_order CHAR(100) NOT NULL,
reservation_from DATE NOT NULL,
reservation_to DATE NOT NULL,
);
ALTER TABLE order ADD CONSTRAINT order_pk PRIMARY KEY ( id_order );
CREATE TABLE room (
num_room CHAR(100) NOT NULL,
type VARCHAR2(100) NOT NULL,
);
ALTER TABLE room ADD CONSTRAINT room_pk PRIMARY KEY ( num_room );
CREATE TABLE reserving (
room_num_room CHAR(100) NOT NULL,
order_id_order CHAR(100) NOT NULL
);
ALTER TABLE reserving ADD CONSTRAINT reserving_pk PRIMARY KEY ( room_num_room,
order_id_order );
ALTER TABLE reserving
ADD CONSTRAINT reserving_order_fk FOREIGN KEY ( order_id_order )
REFERENCES order ( id_order );
ALTER TABLE reserving
ADD CONSTRAINT reserving_room_fk FOREIGN KEY ( room_num_room )
REFERENCES room ( num_room );
I tried recreating the trigger with the statements above. The statements failed with several errors, it looks as if they were not tested before posting them as question. Please take some time posting a quality question.
Example:
CREATE TABLE room (
num_room CHAR(100) NOT NULL,
type VARCHAR2(100) NOT NULL, << this trailing comma makes this statement fail.
);
After fixing all errors I ran the "CREATE TRIGGER" and it errored out with
PLS-00049: bad bind variable 'NEW.ROOM_NUM_ROOM'
That is because the column ROOM_NUM_ROOM does not exist in the "ORDER" table.
If I remove the reference to 'NEW.ROOM_NUM_ROOM' the trigger compiles successfully.
However, as gsalem pointed out, this will not work because it will raise a mutating table error. In the trigger code you cannot execute DML referencing the table that the trigger is on. There is plenty of documentation on how to avoid mutating table errors.

CHECK constraint failed

I'm using sqlite3
I have created a table of a class like this
CREATE TABLE Class (
ClassID char(5) PRIMARY KEY CHECK (ClassID LIKE 'CT[1-9][A-Z]' OR 'AT[1-9][1-9][A-Z]'),
ClassQuantity int NOT NULL CHECK (ClassQuantity > 0)
);
And when I insert some values to this table
INSERT INTO Class
VALUES ('CT2D', 50);
It shows me an error message
'CHECK constraint failed'.
I have written the values based on the condition in the check. Can someone help me with this problem.
You miss to write the OR condition there OR ClassID LIKE 'AT[1-9][1-9][A-Z]'
CREATE TABLE Class (
ClassID char(5) PRIMARY KEY
CHECK (ClassID LIKE 'CT[1-9][A-Z]' OR ClassID LIKE 'AT[1-9][1-9][A-Z]'),
ClassQuantity int NOT NULL CHECK (ClassQuantity > 0)
);
INSERT INTO Class
VALUES ('CT2D', 50);
The LIKE expression in your check constraint is trying to use the extended syntax supported by databases like SQL Server and Sybase. However, I don't think this syntax is supported by SQLite. As a workaround, if your version of SQLite has REGEXP, we can use that instead:
CREATE TABLE Class (
ClassID char(5) PRIMARY KEY CHECK (ClassID REGEXP 'CT[1-9][A-Z]|AT[1-9][1-9][A-Z]'),
ClassQuantity int NOT NULL CHECK (ClassQuantity > 0)
);
use GLOB(). as mentioned here
CREATE TABLE Class (
ClassID char(5) PRIMARY KEY
CHECK (ClassID GLOB 'CT[1-9][A-Z]' OR ClassID GLOB 'AT[1-9][1-9][A-Z]'),
ClassQuantity int NOT NULL CHECK (ClassQuantity > 0)
);
INSERT INTO Class
VALUES ('CT2D', 50);
sqlite dbfiddle

Error in primary key in sqlplus?

I am beginner in sql.I am using sqlplus to run the sql query .I used simple query but it shows an error like "MISSING RIGHT PARENTHESIS".My objective is to create the autoincrement primary key .Can anyone solve the error?Thanks in advance...
create table student(rollno int identity(1,1) primary key,
name varchar(20),marks int);
For Oracle, the rollno column could be defined as NUMBER(0010) and primary key.
Then you would need to add an ON INSERT trigger to populate rollno from a SEQUENCE. There are many samples of triggers and sequences on this site.
In oracle 12 you can use a identity column to automatically fill your ID
CREATE TABLE students
(
"ID" NUMBER GENERATED BY DEFAULT AS IDENTITY MINVALUE 1 MAXVALUE 9999999999
INCREMENT BY 1 START WITH 1 ,
"NAME" VARCHAR2(20),
"MARKS" NUMBER(2,0),
CONSTRAINT PK_STUDENTS PRIMARY KEY (ID) ENABLE
);
/
This creates a table without any triggers needed and automatically fills the id column (of not specified with a value) with the next number up to 99999...
If you're using oracle 11 and below, you need a trigger on insert and assign a value (custom_sequence.nextval) to the id column.
CREATE TABLE students
(
"ID" NUMBER(5,0) not null,
"NAME" VARCHAR2(20),
"MARKS" NUMBER(2,0),
CONSTRAINT PK_STUDENTS PRIMARY KEY (ID) ENABLE
);
/
CREATE SEQUENCE SEQ_STUDENTS INCREMENT BY 1 START WITH 1;
/
TRIGGER TC_students
before insert on students
for each row
begin
if (:new.id is null) then
select SEQ_students.nextval into :new.id from dual;
end if;
end;
/
And please use VARCHAR2.

Setting a column based on conditions when INSERTING data in ORACLE

Currently working on a basketball performance database. The issue I'm having is storing the winner of a match.
Match table is currently like so:
CREATE TABLE Matches(
M_ID int CONSTRAINT pk_Match PRIMARY KEY,
M_Date Date NOT NULL,
M_Location varchar(20),
M_HomeTeam int NOT NULL,
M_AwayTeam int NOT NULL,
M_HomeScore int NOT NULL,
M_AwayScore int NOT NULL,
M_Winner int,
CONSTRAINT fk_TeamHome foreign key (M_HomeTeam) REFERENCES Team(T_ID),
CONSTRAINT fk_TeamAway foreign key (M_AwayTeam) REFERENCES Team(T_ID)
)
What I want is the value of M_Winner to be set to M_HomeTeam & M_AwayTeam foreign keys based on their scores.
I've been able to do this with this update statement
UPDATE Matches
SET M_Winner = CASE
WHEN M_HomeScore > M_AwayScore
THEN M_HomeTeam
WHEN M_AwayScore > M_HomeScore
THEN M_AwayTeam
END;
However I need it to work when the data is inserted.
Any ideas?
In Oracle 11g+, you can use a virtual computed column:
ALTER TABLE matches
ADD m_winner as (CASE WHEN M_HomeScore > M_AwayScore
THEN M_HomeTeam
WHEN M_AwayScore > M_HomeScore
THEN M_AwayTeam
END)
You can define a trigger for that:
CREATE OR REPLACE TRIGGER trg_ins_match
BEFORE INSERT ON Matches
FOR EACH ROW
BEGIN
IF :new.M_HomeScore > :new.M_AwayScore THEN
:new.M_Winner = :new.M_HomeTeam
ELSE
:new.M_Winner = :new.M_AwayTeam
END IF;
END;
Read about triggers in the Oracle Developer's Guide

CHECK CONSTRAINT on multiple columns

I use SQL Server 2008
I use a CHECK CONSTRAINT on multiple columns in the same table to try to validate data input.
I receive an error:
Column CHECK constraint for column
'AAAA' references another column,
table 'XXXX'.
CHECK CONSTRAINT does not work in this way.
Any other way to implement this on a single table without using FK?
Thanks
Here an example of my code
CREATE TABLE dbo.Test
(
EffectiveStartDate dateTime2(2) NOT NULL,
EffectiveEndDate dateTime2(2) NOT NULL
CONSTRAINT CK_CmsSponsoredContents_EffectiveEndDate CHECK (EffectiveEndDate > EffectiveStartDate),
);
Yes, define the CHECK CONSTRAINT at the table level
CREATE TABLE foo (
bar int NOT NULL,
fred varchar(50) NOT NULL,
CONSTRAINT CK_foo_stuff CHECK (bar = 1 AND fred ='fish')
)
You are declaring it inline as a column constraint
...
fred varchar(50) NOT NULL CONSTRAINT CK_foo_fred CHECK (...)
...
Edit, easier to post than describe. Fixed your commas.
CREATE TABLE dbo.Test
(
EffectiveStartDate dateTime2(2) NOT NULL,
EffectiveEndDate dateTime2(2) NOT NULL, --need comma
CONSTRAINT CK_CmsSponsoredContents_EffectiveEndDate CHECK (EffectiveEndDate > EffectiveStartDate) --no comma
);
Of course, the question remains are you using a CHECK constraint where it should be an FK constraint...?
Check constraints can refer to a single column or to the whole record.
Use this syntax for record-level constraints:
ALTER TABLE MyTable
ADD CONSTRAINT MyCheck
CHECK (...your check expression...)
You can simply apply your validation in a trigger on the table especially that either way the operation will be rolled back if the check failed.
I found it more useful for CONSTRAINT using case statements.
ALTER TABLE dbo.ProductStock
ADD
CONSTRAINT CHK_Cost_Sales
CHECK ( CASE WHEN (IS_NOT_FOR_SALE=0 and SAL_CPU <= SAL_PRICE) THEN 1
WHEN (IS_NOT_FOR_SALE=1 ) THEN 1 ELSE 0 END =1 )