Constraint Problem - sql-server

I created the following table
create table publisher(name varchar(20), city varchar(20));
I want to put following constraint, 'name is having unique with city taken only from 'mumbai', 'pune', 'nasik', 'panji''. I know about unique constraints with name. I searched many about constraint with city, but i don't get it till now. Will you please help me about constraint. I used 'BETWEEN' constraint, but it failed. What should I do?

You can use IN instead of BETWEEN
CREATE TABLE publisher
(
name VARCHAR( 20 ) UNIQUE
, city VARCHAR( 20 ) CHECK ( city IN ('a', 'b') )
);
INSERT INTO publisher
VALUES ('hi','a'); -- Succeeds
INSERT INTO publisher
VALUES ('hi','b'); -- Fails, already have 'hi'
INSERT INTO publisher
VALUES ('hj','c'); -- Fails, 'c' is not a city

I think you're asking for names to be unique within their city, and for the cities to come from a fixed list of possibilities?
If so, the following would work:
create table publisher(
name varchar(20),
city varchar(20),
constraint UQ_NamesWithinCities UNIQUE (name,city),
constraint CK_CityNames CHECK (city in ('mumbai', 'pune', 'nasik', 'panji'))
);

Related

Mass data loading on table where foreign key reference primary key in same table

I'm teaching myself SQL Server but have a background with "relational" databases for many years and understand keys and their linking relationships.
I have list of pre-defined INSERTS that I found somewhere and am trying and create a "employees" table. Within the table is a primary key on employee_id and with a foreign key on manager_id, references back to employee_id creating a hierarchy.
(
employee_id NUMERIC(3)
PRIMARY KEY,
first_name VARCHAR( 255 ) NOT NULL,
last_name VARCHAR( 255 ) NOT NULL,
email VARCHAR( 255 ) NOT NULL,
phone VARCHAR( 50 ) NOT NULL ,
hire_date DATE NOT NULL ,
manager_id NUMERIC(3) , -- fk
job_title VARCHAR( 255 ) NOT NULL,
CONSTRAINT fk_employees_manager
FOREIGN KEY( manager_id )
REFERENCES employees( employee_id )
ON DELETE NO ACTION
)
Here is snipet of INSERTS:
Insert into EMPLOYEES
(EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (107,'Summer','Payne','summer.payne#example.com','515.123.8181','07-JUN-16',106,'Public Accountant');
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (106,'Rose','Stephens','rose.stephens#example.com','515.123.8080','07-JUN-16',2,'Accounting Manager');
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (101,'Annabelle','Dunn','annabelle.dunn#example.com','515.123.4444','17-SEP-16',2,'Administration Assistant');
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (1,'Tommy','Bailey','tommy.bailey#example.com','515.123.4567','17-JUN-16',null,'President');
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (3,'Blake','Cooper','blake.cooper#example.com','515.123.4569','13-JAN-16',1,'Administration Vice President');
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (2,'Jude','Rivera','jude.rivera#example.com','515.123.4568','21-SEP-16',1,'Administration Vice President');
Insert into EMPLOYEES (EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE,HIRE_DATE,MANAGER_ID,JOB_TITLE) values (11,'Tyler','Ramirez','tyler.ramirez#example.com','515.124.4269','28-SEP-16',9,'Accountant');
Upon trying to INSERT the data, I get an error stating:
The INSERT statement conflicted with the FOREIGN KEY SAME TABLE constraint "fk_employees_manager". The conflict occurred in database "MyDB", table "dbo.employees", column 'employee_id'.
I understand I'm trying to add employee 107 with a manager id of 106 but as being the first INSERT, employee (or a manager) id 106 doesn't exist (yet).
So my quick solution was to create the employees table WITHOUT to foreign key, execute all of the inserts, then finally ALTER the employees table to add the foreign key on manager_id referencing to employee_id.
This worked with no errors.
But I'd like to know if there is a better way to do this. I'm semi aware of the ON CASCADE ON UPDATE, etc features on adding a foreign key, but not sure how/syntax to make this work when creating the table (before data loading).

How should a IsPrimaryPhone field be modeled in the database?

A contact can have one or more phone numbers. A way is needed to set one of them as the "Primary" phone number.
What is the best way to model that?
The way I usually see it done is to simply add a field called "is_primary" to the phone. Yet for this to work, when that field is set to true for one record, then all other related phone numbers needs to be set to false.
Is there a way to model it through a relation so only one bit of data needs to be updated?
It seems this could be done through a linking table called PrimaryPhone with
ContactId and PhoneId. If the link exists for a ContactId/PhoneId, then it would be used in the UI to show that it was the primary. If the primary changed, it would only be a matter of changing the one record.
Or is some other way this should be done?
Assuming you have two tables (Contacts and PhoneNumbers) it is pretty simple. You have a column in Contacts for PrimaryPhoneNumberID and it contains the ID of the PhoneNumber. This ensures you can never have more than 1 marked as the primary at any one point in time.
I might try mine like:
CREATE TABLE Contact
(ContactID int NOT NULL PRIMARY KEY
,CreateDate datetime
)
GO
CREATE TABLE Phone
(PhoneID int identity (1,1) PRIMARY KEY
,ContactID int not null
,[Key] varchar(20) not null
,[Value] varchar(20) not null
,[Status] varchar(20) not null
)
GO
ALTER TABLE Phone
ADD CONSTRAINT FK_cnst FOREIGN KEY (ContactID)
REFERENCES Contact (ContactID)
GO
ALTER TABLE phone ADD CONSTRAINT UX_Constraint UNIQUE (ContactID, [Status])
GO
INSERT contact SELECT 1, GETDATE()
INSERT INTO phone (ContactID, [Key], Value, Status) VALUES (1, 'Office', '455-1212', 'Alternate')
INSERT INTO phone (ContactID, [Key], Value, Status) VALUES (1, 'Home', '555-1212', 'Alternate2')
INSERT INTO phone (ContactID, [Key], Value, Status) VALUES (1, 'Cell', '555-1000', 'Primary')
INSERT INTO phone (ContactID, [Key], Value, Status) VALUES (1, 'Cell', '555-1001', 'MistressHotline')
GO
SELECT *
FROM Phone
GO
DROP TABLE phone, Contact
And then of course go query it to see if it will work out or not.
Thanks

What is wrong with this insert statement?

Given the following two tables:
CREATE TABLE Members(
email VARCHAR(20) PRIMARY KEY,
password VARCHAR(20),
pref_game_genre VARCHAR(20)
)
CREATE TABLE Normal_Users(
email VARCHAR(20) PRIMARY KEY FOREIGN KEY REFERENCES Members,
first_name VARCHAR(20),
last_name VARCHAR(20),
date_of_birth date,
age as (YEAR(CURRENT_TIMESTAMP) - YEAR(date_of_birth))
)
I am trying to execute the following insert statement:
INSERT INTO Normal_Users VALUES('testemail#gmail.com', 'Adam', 'Robert', '05-04-1990')
But I am getting the following error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK__Normal_Us__email__74994623". The conflict occurred in database "DatabasesProject", table "dbo.Members", column 'email'.
The statement has been terminated.
What am I doing wrong?
You have to populate Members table first.
INSERT INTO Members(email) VALUES('testemail#gmail.com')
INSERT INTO Normal_Users VALUES('testemail#gmail.com', 'Adam', 'Robert', '05-04-1990')
On Normal_Users you are setting email as the primary key AND foreign key.
A better solution is to set email only as foreign key and choose another as primary key (maybe a generated id).

How to set "auto insert" foreign key value by using SQL Server?

I have created two tables and also created a relationship between them.
Table students:
create table students
(
[StudentId] NVARCHAR(50) NOT NULL PRIMARY KEY,
[Name] NVARCHAR(50) NOT NULL
);
Table studentprofile:
create table studentprofile
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
[StudentId] NVARCHAR(50) NOT NULL,
[Address] NVARCHAR(50) NOT NULL,
);
and relationship:
alter table studentprofile
add constraint students_studentprofile_FK
foreign key (StudentId)
references students(StudentId)
on delete cascade on update cascade
But, when I wrote this line:
insert into students values('110111', 'Marik')
the value of StudentId (in table studentprofile) wasn't updated automatically. Why?
Can you tell me how to set the value of StudentId (in table studentprofile) can be inserted automatically whenever I insert into table students?
There is no such thing as insert cascade.
You can implement such a thing by using a trigger for insert on your students table, inserting default values (or nulls) into the studentprofile table:
CREATE TRIGGER students_insert ON students AFTER INSERT
AS
INSERT INTO studentprofile(StudentId, Address)
SELECT StudentId, 'NO ADDRESS'
FROM inserted
Note that your Address column is defined as not null and has no default value, this is why I've used the hard coded 'NO ADDRESS' for it.
However, I agree with the comments on your question: you would be better off inserting the data to the student profile using a different insert statement (perhaps inside a transaction with the insert to students).

Using SCOPE_IDENTITY() in a constraint

I am aware that using IDENT_CURRENT will not always return me the correct identity value (especially true in multi-threaded applications). I wanted to use SCOPE_IDENTITY() instead.
For example this is my Employee table:
create table Employee
(
ID int identity(1,1),
Name varchar(20),
SystemID int,
constraint Employee_PK primary key (ID asc)
)
I have a statement below:
alter table Employee
add constraint Employee_D1 default ident_current('Employee') for SystemID
which I need to modify to use SCOPE_IDENTITY() instead.
I tried the below:
alter table Employee
add constraint Employee_D1 default SCOPE_IDENITITY() for SystemID
This did not give any errors. But upon inserting a row, I did not see this column getting updated with the identity value. What am I doing wrong?
Note that the SystemID must not be readonly, so computed field isn't an option.
My exercise here is to try eliminating entry of wrong IDENTITY value in SystemID in case parallel processes try to insert rows.
Just re-read your answer. SystemID isn't an identity column. I don't think you can use SCOPE_IDENITITY() as it hasn't added the row and retrieved the new Identity value at the point it would need the value to save.
What you will need to do is create a trigger After Insert of the row to update the SystemId value. CREATE TRIGGER
Here's how I'd approach this problem (apologies for the poor field names, I'm not feeling inventive)
CREATE TABLE employees (
id int identity(1,1) NOT NULL
, name varchar(20) NOT NULL
, actual_system_id int NULL
, system_id As Coalesce(actual_system_id, id)
, CONSTRAINT pk_employees PRIMARY KEY (id)
)
;
INSERT INTO employees (name)
VALUES ('John')
, ('Paul')
, ('George')
, ('Ringo')
;
SELECT id
, name
, system_id
FROM employees
;
UPDATE employees
SET actual_system_id = 937
WHERE name = 'George'
;
SELECT id
, name
, system_id
FROM employees
;

Resources