Check constraint not reading [A-Z]? - sql

I am having an issue with a check constraint reading [A-Z].
here is the code:
drop table test CASCADE CONSTRAINTS;
Create table test (
post Varchar2(6),
CHECK (post like '[A-Z]')
);
insert into test values ('A');
And I receive a "check constraint violated" error after trying to insert A. Any feedback would be appreciated. Even if it does work for you because everything is telling me it should work.

Use REGEXP_LIKE:
CREATE TABLE test (
post Varchar2(6),
CHECK (REGEXP_LIKE(post, '^[A-Z]+$'))
);
The pattern ^[A-Z]+$ would match posts which only contain capital letters. If instead you want to flag posts which begin with a capital letter, then use ^[A-Z].

Related

Oracle SQL Developer regex expression error

In the script file, I inserted the following code.
drop table Test;
create table Test(
name char(2) unique not null,
constraint name_c check(
regexp_like(name, '^[A-Z]{1,2}$', 'c')
)
);
insert into Test values ('B');
The developer never budge. It keeps on saying violating the name_c constraint and I don't understand why. The regular expression looks fine for me.
Some variants, however, succeeded, for example, dropping the dollar sign
drop table Test;
create table Test(
name char(2) unique not null,
constraint name_c check(
regexp_like(name, '^[A-Z]{1,2}', 'c')
)
);
insert into Test values ('B');
And I don't understand either.
Why?
Edit: This is the problem: logically the regex is right. But somehow Oracle SQL Developer doesn't budge.
if you went it to start with 1 or 2 capital letter and doesn't matter what coming next you should do it like this :
^[A-Z]{1,2}.*
.* mean 1 or more character exept \n (nex line)

Oracle Apex 5 Error, ORA-00907: missing right parenthesis. Can't see missing parenthesis?

I have this code, and cannot work out why I am getting issues. Can anyone help? It executes the generate sequence command, but not the create tables one, so I therefore cannot see it on the object browser.
If this helps:
QuizID is to be generated by a sequence.
QuizTitle, is at most 15 characters, and is not null.
Category is to default to Music with Sports and Geography as the only other available options.
SQL code:
CREATE TABLE Quiz_NLB_2
(
QuizID NUMBER,
QuizTitle VARCHAR2(15) NOT NULL,
Category VARCHAR2(9) DEFAULT 'Music',
CONSTRAINT pk_QuizID PRIMARY KEY (QuizID),
CONSTRAINT chk_Category CHECK (Category='Music', 'Sports', 'Geography')
);
CREATE SEQUENCE QuizID_Sequence_Gen START WITH 100;
The check constraint should look like this:
CONSTRAINT chk_Category
CHECK (Category IN ('Music', 'Sports', 'Geography'))

Multiple constraints on a single column

I want to ensure that only the values 'Expert', 'Average' or 'Adequate' are entered into the levelOfExpertise column of this table, however whenever I do try an enter one of those values, it returns an error saying the value entered is too short. Here is the create table query for this particular table. The the column I am referring to is levelOfExpertise:
CREATE TABLE MusicianInstrument
(
musicianNo varchar(5) not null
CONSTRAINT MI_PK1 REFERENCES Musician(musicianNo),
instrumentName varchar(50) not null
CONSTRAINT MI_PK2 REFERENCES Instrument(instrumentName),
levelOfExpertise varchar(50),
CONSTRAINT levelOfExpertise CHECK (levelOfExpertise = 'Expert', 'Adequate', 'Avergage'),
PRIMARY KEY(musicianNo,instrumentName)
);
Any ideas how I can ensure only those three values (Expert, Adequate or Average) can be entered?
Thanks
Use the IN operator
CHECK (levelOfExpertise IN ('Expert','Adequate','Avergage'))
Try to change your CHECK constraint as following:
CONSTRAINT levelOfExpertise CHECK (levelOfExpertise IN ('Expert','Adequate','Avergage'))
I suppose that you use sql server as RDBMS.

SQL (oracle) Check Constraint difficulty - Not sure how to implement

I am creating a small database for a telecom system.
One of the tables (calls) requires that a if a phone number's area code is not contained in a predefined list, then the number should not be added to the table.
The way I have thought about doing this is to put a check constraint within the calls table to not accept numbers that are not a part of this mentioned list. However, this list is quite long and I am not too sure if there would be a better implementation method.
Here is the list:
01 or 02: local/national number. Ex.: 01612 338866.
075, 077, 078, 079: mobile phone number. Ex.: 07747 556647.
0800: free number. Ex.: 08002 223344.
0845, 0870: special service. Ex.: 08451 423456.
08442 to 08449: 5p special service. Ex.: 08444 404404.
08712 to 08719: 10p special service. Ex.: 08713 457893.
090, 091, 098: premium rate special service. Ex.: 09119 229595.
The only way I could think of to do this is as follows:
ALTER TABLE calls ADD (CONSTRAINT area_ck
CHECK area_code ("01" or "02" or "075" or "077" or "078" or "079" or "0800" or
"0845" or "0870" or (BETWEEN ("08442" AND "08449")) or
(BETWEEN ("08712" AND "08719")) or
"090" or "091" or "098")
) ;
My two main issues with this are:
It gives an error as it is implemented incorrectly
If I were to modify it slightly until it did work, would it still be a long way about trying to solve my task?
The more common approach would be to define a table of valid area codes
CREATE TABLE area_code (
area_code VARCHAR2(5) PRIMARY KEY
);
Fill the Area_Code table with the set of valid values
INSERT INTO area_code( area_code ) VALUES( '01' );
INSERT INTO area_code( area_code ) VALUES( '02' );
INSERT INTO area_code( area_code ) VALUES( '075' );
...
or
BEGIN
FOR i IN 1000 .. 2999
LOOP
INSERT INTO area_code( area_code )
VALUES( to_char( i, '00000' ) );
END LOOP;
END;
And then define a foreign key constraint from your Call table to the Area_Code table
CREATE TABLE call (
call_id NUMBER PRIMARY KEY,
area_code VARCHAR2(5) REFERENCES area_code( area_code ),
<<other columns>>
);
That's going to be more efficient to enforce than a CHECK constraint and it will be easier to list the valid area codes.
The first problem is about using = and between together. Do it like:
area_code in ('01', '02', '03') or area_code between ('1000' and '1500') or ....
You could either write area_code='01' OR area_code='02' ... or you can use area_code in ('01','02', ...). You also need to add area_code before between keywords.
But I would suggest you to store the area codes in a table instead of the check constraint and use the area codes as foreign keys. This way the list of area codes can easily be modified.

Errors in my schema creation script

So I have a simple SQL script which creates a database schema of a simple library online catalog:
DROP TABLE book_copies;
/
DROP TABLE books_authors_xref;
/
DROP TABLE authors;
/
DROP TABLE books;
/
CREATE TABLE books (
isbn VARCHAR2(13) NOT NULL PRIMARY KEY,
title VARCHAR2(200),
summary VARCHAR2(2000),
date_published DATE,
page_count NUMBER
);
/
CREATE TABLE authors (
name VARCHAR2(200) NOT NULL PRIMARY KEY
);
/
CREATE TABLE books_authors_xref (
author_name VARCHAR2(200),
book_isbn VARCHAR2(13),
CONSTRAINT pk_books_authors_xref PRIMARY KEY (author_name, book_isbn),
CONSTRAINT fk_books_authors_xref1 FOREIGN KEY (author_name) REFERENCES authors (name),
CONSTRAINT fk_books_authors_xref2 FOREIGN KEY (book_isbn) REFERENCES books (isbn)
);
/
CREATE TABLE book_copies (
barcode_id VARCHAR2(100) NOT NULL PRIMARY KEY,
book_isbn VARCHAR2(13),
CONSTRAINT fk_book_copies FOREIGN KEY (book_isbn) REFERENCES books (isbn)
);
/
Whenever I run it through SQL*Plus, I get many errors during its execution even though it looks like all SQL orders execute properly. This is the output I get:
What does that mean? Am I doing something wrong?
The / in SQL*Plus executes the "command in the buffer". A statement terminated with a semicolon is executed and put into the buffer.
So the CREATE TABLE books .... is actually run twice. The first time because of the semicolon ; (which puts the statement into the buffer) and the second time when the parser hits the /.
That's why you get the "name is already used" error.
So you need to use either a semicolon or a slash, but not both.
Edit
You can see what's going on, when manually running a statement using both, in the following log I copied & pasted the first statement from your script to a SQL*Plus console:
SQL> DROP TABLE book_copies;
Table dropped.
SQL> /
DROP TABLE book_copies
*
ERROR at line 1:
ORA-00942: table or view does not exist
You can see clearly how the DROP TABLE is execute because of the semicolon, and how the / executes it again.