Check constraint last_name capitalized - sql

How can I make a check constraint that checks if last_name has the last 2 letters capitalized?
alter table clienti modify (nume_client constraint che_d check(nume_client=upper(substr(nume_client, -2, 1))));
I did like this, but I am getting the following error:
00000 - "cannot validate (%s.%s) - check constraint violated"

Your constraint is comparing the whole name to the upper-cased second-to-last character. It's only looking at one character, because you're supplying the third argument substring_length as 1. You need to check the last two characters; so you need to compare only those with the same two characters in upper-case:
substr(nume_client, -2) = upper(substr(nume_client, -2))
The error you are getting is because you have existing data which does not satisfy the constraint you are trying to add. That may be because your constraint isn't doing what you intended, as it will always return false in your original version.
If you get the same error with the modified check then you either need to remove or correct that data before you add the constraint, or use the novalidate clause:
check (substr(nume_client, -2) = upper(substr(nume_client, -2))) novalidate
Any existing constraint-violating rows will remain untouched, but you won't be able to add new rows that violate the constraint, or update existing rows to still-invalid values.
You can use your alter table modify (column...) syntax, or the simpler syntax Gordon Linoff showed; they do the same thing ultimately.

You might already have records there in table, that do not pass the check constraint. If it's OK to have the check only for future transactions you can use NOVALIDATE clause to constraint. E.g.
CREATE TABLE names (last_name VARCHAR2(100));
--Table created
INSERT INTO names VALUES ('Rambo');
--1 row inserted
INSERT INTO names VALUES ('GatES');
--1 row inserted
alter table names add constraint chk_che_d
check (SUBSTR(last_name,-2,1) = upper(substr(last_name, -2, 1))) NOVALIDATE;
--Table altered
INSERT INTO names VALUES ('Travolta');
--ORA-02290: check constraint (RO.CHK_CHE_D) violated
INSERT INTO names VALUES ('SkywalkER');
--1 row inserted

This is the syntax for adding a check constraint:
alter table clienti add constraint chk_che_d
check (nume_client = upper(substr(nume_client, -2, 1)));
I'm pretty sure the logic doesn't do anything useful (I'm pretty sure this will always return false). But the right syntax will get you on the right path.

Related

How to create CHECK constraints in Informix?

I need to create validations in my fields (columns) in Informix tables. Inside SQL Server, the names are CHECK (for example: CHECK (Age>=18))
How to create in Informix, or, what's the similar syntax in Informix?
If you want add check constraint you could do it in two ways:
1) The next example adds a new unit_price column to the items table and includes a check constraint to ensure that the entered value is greater than 0:
ALTER TABLE items
ADD (unit_price MONEY (6,2) CHECK (unit_price > 0));
2) To create a constraint that checks values in more than one column, use the ADD CONSTRAINT clause. The following example builds a constraint on the column that was added in the previous example. The check constraint now spans two columns in the table.
ALTER TABLE items ADD CONSTRAINT CHECK (unit_price < total_price);
Have a look at the doc

PL/SQL constraint: Always one record in a table

Im trying to add a constraint to a table so that there can only be one record in the table.
This is the code I already have:
ALTER TABLE CONFIG
ADD CONSTRAINT always_one
CHECK (count(*)= 1);
And this is the error I'm getting
ALTER TABLE CONFIG
ADD CONSTRAINT always_one CHECK (count(*)= 1)
Error report -
SQL Error: ORA-00934: group function is not allowed here
00934. 00000 - "group function is not allowed here"
*Cause:
*Action:
How does this work?
You can use already proposed solution with adding unique constraint on column
alter table config add constraint always_one check (pk_col=1);
this however allows inserting more than one row in case pk_col is null in second inserted row. So you need to handle this by adding a NOT NULL constraint as well
ALTER TABLE config
ADD CONSTRAINT notnulc CHECK (pk_col IS NOT NULL) ;
To prevent deleting this row, you should probably create before delete trigger as follows
create or replace trigger trg_ONLYONE before delete ON CONFIG
DECLARE
C NUMBER;
BEGIN
SELECT COUNT(*) INTO C FROM CONFIG;
if (C=1) THEN
RAISE_APPLICATION_ERROR (-20011, 'TOO FEW ROWS');
END IF;
END;
Futher options are: instead of check constraints mentioned above is CREATE BEFORE INSERT trigger, or instead of NOT NULL and UNIQUE CONSTRAINT make pk_col PRIMARY KEY
Just create a unique index on a column in the table, and add a constraint that the value of this column must be a certain value.
eg.
CREATE UNIQUE INDEX one_val ON config(pk_col);
ALTER TABLE CONFIG
ADD CONSTRAINT always_one
CHECK (pk_col = 1);
If all of your other columns could be any value, you may need to just add this additional column, and give it a default value.

Oracle Constraints error

I have a table x, and added a new column abc of number data type. New column successfully loaded with null values into table x.
When I was trying to add the same column with not null constraint, its giving an error : "table must be empty to add mandatory (not null) column"
I expected an error because as there is no data in it, I can't use not null constraint. But, what was not expecting this error. Why must the table be empty to add that constraint ? Could some one explain ?
It is because the null constraint is immediately violated as soon as you create the column. You could perhaps supply a default value.
An empty table would not have this problem due to lack of rows.
If you don't have data in the table, NOT NULL constraint is not violated. But if you have at least a single row, the constraint is violated because database have to create a column value for each row as NULL.
You can use a default value to overcome this issue:
ALTER TABLE tablename
ADD column_name NUMBER NOT NULL
DEFAULT '*';

How do I put a check constraint on the first letter of names in Oracle

I am new at SQLPlus and I want to enforce a CHECK CONSTRAINT on a column that stores names.
I want the constraint to not allow for names to be entered that starts with a Q.
this is what I have:
ALTER TABLE table1 ADD CONSTRAINT table1_name_ck CHECK( name, substr(1,1) ='q');
I am getting the errors:
cannot validate (USER1.TABLE1_NAME_CK) - check constraint violated
AND errors
CHECK( name, substr(1,1) ='q')
*
ERROR at line 2:
ORA-00920: invalid relational operator.
I cannot figure out how to fix these errors or find the correct way to implement this. Any advice would be appreciated! Thanks!. I don't think this code work for lowercase q and uppercase Q but I'm just trying that out for now.
You need to pass the column to the substr call:
ALTER TABLE table1
ADD CONSTRAINT table1_name_ck CHECK( substr(name, 1,1) ='q' );
To make this work for upper and lowercase you need to enhance this a bit:
ALTER TABLE table1
ADD CONSTRAINT table1_name_ck CHECK( substr(name, 1,1) NOT IN ('q','Q') );

INSERT statement conflicted with COLUMN FOREIGN KEY

I have a FK in my table that looks like this:
Clearly, I should be able to insert NULL into this column as well as any value that exists in the parent table.
But when I try to insert NULL, I get the following error:
The INSERT statement conflicted with the FOREIGN KEY constraint
"users_fk". The conflict occurred in database "mydatabase", table
"dbo.country", column 'country_id'.
You are absolutely right - you should be able to insert NULL into this column.
Are you 500% sure that you are? The error message says something else - it appears as if you're inserting an invalid value.
Could it be that you have
(a) another line in your script that inserts additional (invalid) values?
Or
(b) do you happen to have a trigger on this table that does something invalid?
Update: (based on your comment)
If you're not specifying the column in the INSERT statement - then maybe an invalid default value is defined on that column? Something like a default of 0 or something.
If you do have a default value - that default value will be inserted (and not NULL, as you seem to be expecting)