Multiple constraints on a single column - sql

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.

Related

CHECK with ^[A-Z]{3}[0-9]{6}$ - SQL Server

CREATE TABLE PARTICIPANTE(
pasaporte NVARCHAR(9) NOT NULL,
nombre NVARCHAR(50) NOT NULL,
sexo CHAR(1) NOT NULL,
fecNac DATE NOT NULL,
codPais NVARCHAR(3) NOT NULL,
CONSTRAINT PK_PARTICIPANTE PRIMARY KEY (pasaporte),
CONSTRAINT FK_PAIS_PARTICIPANTE FOREIGN KEY (codPais) REFERENCES PAIS(codigo),
CONSTRAINT CHK_PASAPORTE CHECK (pasaporte like '^\[A-Z\]{3}\[0-9\]{6}$')
)
The CONSTRAINT CHK_PASAPORTE doesn't work when I try to insert the data.
The INSERT statement conflicted with the CHECK constraint "CHK_PASAPORTE". The conflict occurred in database "OMA", table "dbo.PARTICIPANTE", column 'pasaporte'.
Example
insert into PARTICIPANTE (pasaporte,nombre,sexo,fecNac,codPais) value ('JPN865653','Noguchi','F','20000104','JPN');
Can someone explain to me why this doesn't work and how can I fix it?
As I mention in the comments, SQL Server has no (in built) support for Regex, it only has basic pattern matching, which is explained in the documentation.
Fortunately, the logic you are after appears to be quite simple; 3 letters followed by 6 digits. This can be achieved with the following constraint:
ALTER TABLE dbo.PARTICIPANTE ADD CONSTRAINT CHK_PASAPORTE CHECK (pasaporte LIKE '[A-Z][A-Z][A-Z][0-9][0-9][0-9][0-9][0-9][0-9]');
Note that if you require the value to only contain uppercase values, you'll need to COLLATE the value to a collation that is case sensitive and orders upper case letters first, then lowercase, and finally alphabetically (Binary collations are one such one that does this).

How to add NOT NULL constraint along with default value for the column?

I have a column 'name' in student table. I need to add NOT NULL constraint on this column. But I get SQL error saying cannot add null constraint since the existing rows in the table has null values in the column. How would I add a null constraint along with default value in a single alter statement. Below is my query.
alter table Student alter column name nvarchar NOT NULL;
SQL Server does not make this easy. I think the only way is to set the existing values to the default that you want. Then change the column to have a default value and not null:
-- Get rid of the existing `NULL` values
update students set name = '' where name is null;
-- Add the NOT NULL constraint
alter table students
alter column name varchar(255) not null;
-- Add a default value
alter table students
add constraint df_t_name default '' for name ;
Here is what it looks like in practice.
But I get SQL error saying cannot add null constraint since the existing rows in the table has null values in the column.
Have you tried overwriting the existing NULL values?
You can't have a constraint on a column when existing values would violate that constraint. You need to make your table compliant first.

Avoiding multiple "OR's" in a SQL query

I have the following working SQL query that adds a constraint MindestensEinKontakt_CHECK to the table KundenKontaktDaten. The constrainst ensures that at least one of the attributes Twitter_Id, Google_Id, Facebook_Id, Skype_Id, and Telefonnummer is not null:
ALTER TABLE KundenKontaktDaten
ADD CONSTRAINT MindestensEinKontakt_CHECK
CHECK (Twitter_Id IS NOT NULL OR Google_Id IS NOT NULL OR
Facebook_Id IS NOT NULL OR Skype_Id IS NOT NULL OR
Telefonnummer IS NOT NULL);
I want to avoid the multiple "OR's" and write the query in a more compact way. Is anyone aware of a way to do this?
coalesce returns the first non-null argument, or null if they are all nulls. You could utilize it in your alter table statement:
ALTER TABLE KundenKontaktDaten
ADD CONSTRAINT MindestensEinKontakt_CHECK
CHECK (COALESCE(Twitter_Id, Google_Id, Facebook_Id, Skype_Id, Telefonnummer) IS NOT NULL);

I can't insert null on a Foreign Key

I've tried to search but nothing works, and I don't know what to do.
There's a table with two foreign keys, one of which can be null. According to what I've searched, it's perfectly fine to have null foreign keys. But no matter what, when I try to insert a null in that value, it fails. It says:
*Cause: A foreign key value has no matching primary key value.
*Action: Delete the foreign key or add a matching primary key.
Here is the code of the table. The FK that I want to be null is idPedido
CREATE TABLE PAGOS(
fechaLimite DATE,
cuantia NUMBER NOT NULL,
fechaInicio DATE DEFAULT SYSDATE,
fechaLiquidacion DATE,
idPago VARCHAR(8) NOT NULL,
dni VARCHAR(14) NOT NULL,
tipoPago VARCHAR(7) DEFAULT 'OTRO' CHECK(tipoPAGO IN('MENSUAL','PEDIDO','OTRO')),
idPedido VARCHAR2(10),
PRIMARY KEY(idPago),
FOREIGN KEY(dni) REFERENCES MIEMBROS ON DELETE SET NULL,
FOREIGN KEY(idPedido) REFERENCES PEDIDOS ON DELETE SET NULL
);
There are some triggers and such to add sequences for the idPago value.
Here is the code of the procedure that creates a new item to the table:
create or replace PROCEDURE CREAR_PAGO(
new_fechaLimite IN PAGOS.fechaLimite%TYPE ,
new_cuantia IN PAGOS.cuantia%TYPE,
new_fechaInicio IN PAGOS.fechaInicio%TYPE,
new_fechaLiquidacion IN PAGOS.fechaLiquidacion%TYPE,
new_dni IN PAGOS.dni%TYPE,
new_tipoPago IN PAGOS.tipoPago%TYPE,
new_idPedido IN PAGOS.idPedido%TYPE
)
IS
BEGIN
INSERT INTO PAGOS(fechaLimite,cuantia,fechaInicio,fechaLiquidacion,dni,tipoPago,idPedido) VALUES(new_fechaLimite,new_cuantia,new_fechaInicio,new_fechaLiquidacion,new_dni,new_tipoPago,new_idPedido);
END CREAR_PAGO;
And here is me trying to insert a new element:
execute CREAR_PAGO('01012020',40,'01012010',null,49035480D,null,null);
I've already tried to put both "NULL" and "DEFAULT NULL" in the table code after idPedido's type and nothing works
Please I need help
It looks like the primary key for your table is idPago, but I don't see it in your insert statement. If that is the case, it would appear that your issue is trying to add a record with no primary key...not that the foreign key is null.

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 )