Constraint Check for 10 Digit Character use for Postal Code - sql

I have a table with a Char(10) column type, named postal Code and I need a Constraint check for all values just be 10 digits like 1234567890 and nothing else, I use the following:
CONSTRAINT [CH_PCDigit] CHECK ( [PostalCode] LIKE '%[^0-9]%'),
CONSTRAINT [CH_PCLength] CHECK ( LEN([PostalCode])=10)
but not worked correctly, why? and what is your suggestion? is there any way to merge this 2 constraint with one?
And what about if I want a Postal Code like this: 12345-54321 mean: 5digit-5digit? (Also Type must be Char(11)).
Does any one know any good source for Rgex or Constraint Check in SQl?

SQL Server TSQL does not support full blown RegEx's. You can do what you want in a single constraint like so:
CONSTRAINT [CH_PCDigit]
CHECK ([PostalCode] LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]')
or better:
CONSTRAINT [CH_PCDigit]
CHECK ([PostalCode] LIKE REPLICATE('[0-9]', 10))
If you want to allow dashes:
CREATE table ChkTest
(
PostalCode char(10) not null
CONSTRAINT [CH_PCDigit]
CHECK ([PostalCode] LIKE REPLICATE('[0-9,-]', 10))
)
-- Test Code...
insert into ChkTest
select '1234567890'
insert into ChkTest
select '123456780'
insert into ChkTest
select '12345678y0'
insert into ChkTest
select '12345678901'
select * from ChkTest
insert into ChkTest
select '12345-8901'

Here is one that accepts both U.S. Zip Code and Canada Postal Code.
CONSTRAINT CH_PCDigit
CHECK (PostalCode LIKE '[0-9][0-9][0-9][0-9][0-9]' OR
PostalCode LIKE '[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]' OR
PostalCode LIKE '[A-Y][0-9][A-Z][0-9][A-Z][0-9]')

YOu can use isnumeric, split big number:
CREATE TABLE a (
pc CHAR(10),
CONSTRAINT pc_c CHECK (
LEN(pc) = 10 AND
ISNUMERIC(SUBSTRING(pc,1,5))=1 AND
ISNUMERIC(SUBSTRING(pc,6,5))=1)
)

Related

Constraint that allows only specific characters, MsSQL

Example table declaration:
CREATE TABLE Person (
ID int PRIMARY KEY,
FirstName nvarchar(255),
LastName nvarchar(255),
PhoneNumber varchar(255)
)
How can i add constraint that won't allow adding any letters into PhoneNumber?
You can use a check constraint:
alter table person add constraint chk_person_phonenumber
check (phonenumber not like '%[^0-9]%');
This says that phonenumber has no characters that are not digits.
Note that you an extend the pattern to allow spaces, hyphens, or parentheses, if you really also want those.
If you really just wanted digits, you could also use try_convert():
check (phonenumber not like '%.%' and
try_convert(decimal(38, 0), phonenumber) is not null
)
This is not as flexible for expanding the character set, though.

Why does the zipcode fail the check constraint?

I feel like I am probably missing something really simple, but I really can't figure out what I'm doing wrong. I'm trying to use a check constraint to make sure zipcodes are 5 digit numbers, but the check restraint keeps failing. Here is the table creating with the constraint:
Create Table Students (
StudentID Int Primary Key Identity(1,1)
StudentNumber nVarchar(100) Unique Not Null,
...
StudentZipCode nChar(10) Not Null
)
Go
Alter Table Students Add Constraint chZipCode
CHECK (StudentZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]' OR StudentZipCode
Like '[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
Go
Codes like 12345-6789 work, but when I try to insert the values like '12345' or '01234' it gives me this error:
The INSERT statement conflicted with the CHECK constraint "chZipCode". The conflict occurred in database ..., table "dbo.Students", column 'StudentZipCode'.
It fails because you defined the zip code as a char() instead of a varchar(). Hence, it has a bunch of spaces padding it out.
So, define it as:
Create Table Students (
StudentID Int Primary Key Identity(1,1),
StudentNumber nVarchar(100) Unique Not Null,
StudentZipCode nVarChar(10) Not Null,
CHECK (StudentZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]' OR
StudentZipCode LIKE '[0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]')
);
Then '12345' works, because it matches the first of the LIKE patterns.
'012344' does not work, because no pattern has six digits in a row.
Here is a SQL Fiddle.

Inserting null values when using bulk insert

I have one table:
CREATE TABLE cust (
cust_id NOT NULL,
cust_name NOT NULL,
address NULL
);
I have to insert these rows into another table:
CREATE TABLE 1cust_det (
cust_id NOT NULL,
cust_name NOT NULL,
address NOT NULL
);
Unfortunately the cust.address column contains NULL values. I want to insert these rows from cust to 1cust_det using a cursor. What do I have to do?
INSERT INTO
cust_det
SELECT
cust_id,
cust_name,
COALESCE(address, 'UNKNOWN')
FROM
cust
If you have access to change the destination table, just add a default to the column.
CREATE TABLE 1cust_det (
cust_id NOT NULL,
cust_name NOT NULL,
address NOT NULL DEFAULT 'DEFAULT_VALUE');
or if you can edit the existing destination table and it doesnt get drooped
ALTER TABLE 1cust_det
ALTER address SET DEFAULT 'DEFAULT_VALUE'
The easiest way if you don't have control of the destination table to add a default value to the address column is to use a case statement in the insert itself. In the example below you can also use a ISNULL evaluation, but you might want to search for empty strings as well. Please try to find a better way to insert instead of using a cursor.
INSERT dbo.1cust_det
(cust_id,cust_name,[address])
SELECT cust_id,cust_name,
CASE
WHEN [address] IS NULL THEN 'some default value'
ELSE [address]
END AS [address]
FROM cust
Above answers are correct. You may have another table that may have address for cust_id. Join that table to get missing address. I have seen that in almost all databases, address is stored for every customer. You must get address where address is NULL in the table cust.

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.

Replace into equivalent for postgresql and then autoincrementing an int

Okay no seriously, if a PostgreSQL guru can help out I'm just getting started.
Basically what I want is a simple table like such:
CREATE TABLE schema.searches
(
search_id serial NOT NULL,
search_query character varying(255),
search_count integer DEFAULT 1,
CONSTRAINT pkey_search_id PRIMARY KEY (search_id)
)
WITH (
OIDS=FALSE
);
I need something like REPLACE INTO for MySQL. I don't know if I have to write my own procedure or something?
Basically:
check if the query already exists
if so, just add 1 to the count
it not, add it to the db
I can do this in my php code but I'd rather all that be done in postgres C engine
You have to add a unique constraint first.
ALTER TABLE schema.searches ADD UNIQUE (search_query);
The insert/replace command looks like this.
INSERT INTO schema.searches(search_query) VALUES ('a search query')
ON CONFLICT (search_query)
DO UPDATE SET search_count = schema.searches.search_count + 1;