I have never "hand-coded" object creation code for SQL Server and foreign key decleration is seemingly different between SQL Server and Postgres. Here is my sql so far:
drop table exams;
drop table question_bank;
drop table anwser_bank;
create table exams
(
exam_id uniqueidentifier primary key,
exam_name varchar(50),
);
create table question_bank
(
question_id uniqueidentifier primary key,
question_exam_id uniqueidentifier not null,
question_text varchar(1024) not null,
question_point_value decimal,
constraint question_exam_id foreign key references exams(exam_id)
);
create table anwser_bank
(
anwser_id uniqueidentifier primary key,
anwser_question_id uniqueidentifier,
anwser_text varchar(1024),
anwser_is_correct bit
);
When I run the query I get this error:
Msg 8139, Level 16, State 0, Line 9
Number of referencing columns in
foreign key differs from number of
referenced columns, table
'question_bank'.
Can you spot the error?
And if you just want to create the constraint on its own, you can use ALTER TABLE
alter table MyTable
add constraint MyTable_MyColumn_FK FOREIGN KEY ( MyColumn ) references MyOtherTable(PKColumn)
I wouldn't recommend the syntax mentioned by Sara Chipps for inline creation, just because I would rather name my own constraints.
create table question_bank
(
question_id uniqueidentifier primary key,
question_exam_id uniqueidentifier not null,
question_text varchar(1024) not null,
question_point_value decimal,
constraint fk_questionbank_exams foreign key (question_exam_id) references exams (exam_id)
);
You can also name your foreign key constraint by using:
CONSTRAINT your_name_here FOREIGN KEY (question_exam_id) REFERENCES EXAMS (exam_id)
I like AlexCuse's answer, but something you should pay attention to whenever you add a foreign key constraint is how you want updates to the referenced column in a row of the referenced table to be treated, and especially how you want deletes of rows in the referenced table to be treated.
If a constraint is created like this:
alter table MyTable
add constraint MyTable_MyColumn_FK FOREIGN KEY ( MyColumn )
references MyOtherTable(PKColumn)
.. then updates or deletes in the referenced table will blow up with an error if there is a corresponding row in the referencing table.
That might be the behaviour you want, but in my experience, it much more commonly isn't.
If you instead create it like this:
alter table MyTable
add constraint MyTable_MyColumn_FK FOREIGN KEY ( MyColumn )
references MyOtherTable(PKColumn)
on update cascade
on delete cascade
..then updates and deletes in the parent table will result in updates and deletes of the corresponding rows in the referencing table.
(I'm not suggesting that the default should be changed, the default errs on the side of caution, which is good. I'm just saying it's something that a person who is creating constaints should always pay attention to.)
This can be done, by the way, when creating a table, like this:
create table ProductCategories (
Id int identity primary key,
ProductId int references Products(Id)
on update cascade on delete cascade
CategoryId int references Categories(Id)
on update cascade on delete cascade
)
create table question_bank
(
question_id uniqueidentifier primary key,
question_exam_id uniqueidentifier not null constraint fk_exam_id foreign key references exams(exam_id),
question_text varchar(1024) not null,
question_point_value decimal
);
--That will work too. Pehaps a bit more intuitive construct?
To Create a foreign key on any table
ALTER TABLE [SCHEMA].[TABLENAME] ADD FOREIGN KEY (COLUMNNAME) REFERENCES [TABLENAME](COLUMNNAME)
EXAMPLE
ALTER TABLE [dbo].[UserMaster] ADD FOREIGN KEY (City_Id) REFERENCES [dbo].[CityMaster](City_Id)
If you want to create two table's columns into a relationship by using a query try the following:
Alter table Foreign_Key_Table_name add constraint
Foreign_Key_Table_name_Columnname_FK
Foreign Key (Column_name) references
Another_Table_name(Another_Table_Column_name)
Like you, I don't usually create foreign keys by hand, but if for some reason I need the script to do so I usually create it using ms sql server management studio and before saving then changes, I select Table Designer | Generate Change Script
This script is about creating tables with foreign key and I added referential integrity constraint sql-server.
create table exams
(
exam_id int primary key,
exam_name varchar(50),
);
create table question_bank
(
question_id int primary key,
question_exam_id int not null,
question_text varchar(1024) not null,
question_point_value decimal,
constraint question_exam_id_fk
foreign key references exams(exam_id)
ON DELETE CASCADE
);
Necromancing.
Actually, doing this correctly is a little bit trickier.
You first need to check if the primary-key exists for the column you want to set your foreign key to reference to.
In this example, a foreign key on table T_ZO_SYS_Language_Forms is created, referencing dbo.T_SYS_Language_Forms.LANG_UID
-- First, chech if the table exists...
IF 0 < (
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'T_SYS_Language_Forms'
)
BEGIN
-- Check for NULL values in the primary-key column
IF 0 = (SELECT COUNT(*) FROM T_SYS_Language_Forms WHERE LANG_UID IS NULL)
BEGIN
ALTER TABLE T_SYS_Language_Forms ALTER COLUMN LANG_UID uniqueidentifier NOT NULL
-- No, don't drop, FK references might already exist...
-- Drop PK if exists
-- ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT pk_constraint_name
--DECLARE #pkDropCommand nvarchar(1000)
--SET #pkDropCommand = N'ALTER TABLE T_SYS_Language_Forms DROP CONSTRAINT ' + QUOTENAME((SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
--WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
--AND TABLE_SCHEMA = 'dbo'
--AND TABLE_NAME = 'T_SYS_Language_Forms'
----AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms'
--))
---- PRINT #pkDropCommand
--EXECUTE(#pkDropCommand)
-- Instead do
-- EXEC sp_rename 'dbo.T_SYS_Language_Forms.PK_T_SYS_Language_Forms1234565', 'PK_T_SYS_Language_Forms';
-- Check if they keys are unique (it is very possible they might not be)
IF 1 >= (SELECT TOP 1 COUNT(*) AS cnt FROM T_SYS_Language_Forms GROUP BY LANG_UID ORDER BY cnt DESC)
BEGIN
-- If no Primary key for this table
IF 0 =
(
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'T_SYS_Language_Forms'
-- AND CONSTRAINT_NAME = 'PK_T_SYS_Language_Forms'
)
ALTER TABLE T_SYS_Language_Forms ADD CONSTRAINT PK_T_SYS_Language_Forms PRIMARY KEY CLUSTERED (LANG_UID ASC)
;
-- Adding foreign key
IF 0 = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_NAME = 'FK_T_ZO_SYS_Language_Forms_T_SYS_Language_Forms')
ALTER TABLE T_ZO_SYS_Language_Forms WITH NOCHECK ADD CONSTRAINT FK_T_ZO_SYS_Language_Forms_T_SYS_Language_Forms FOREIGN KEY(ZOLANG_LANG_UID) REFERENCES T_SYS_Language_Forms(LANG_UID);
END -- End uniqueness check
ELSE
PRINT 'FSCK, this column has duplicate keys, and can thus not be changed to primary key...'
END -- End NULL check
ELSE
PRINT 'FSCK, need to figure out how to update NULL value(s)...'
END
I always use this syntax to create the foreign key constraint between 2 tables
Alter Table ForeignKeyTable
Add constraint `ForeignKeyTable_ForeignKeyColumn_FK`
`Foreign key (ForeignKeyColumn)` references `PrimaryKeyTable (PrimaryKeyColumn)`
i.e.
Alter Table tblEmployee
Add constraint tblEmployee_DepartmentID_FK
foreign key (DepartmentID) references tblDepartment (ID)
Related
There are a few questions I have regarding SQL. One issue I deal with is dyslexia, which causes me to mix up certain characters. Can I make things much larger in Azure Data Studio? In addition, I am not sure why I am receiving errors with my code. Below is the error message I am receiving. I have been researching foreign keys but I have not been able to resolve the issue.
Here is the code:
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'Director')
DROP TABLE Director
CREATE TABLE Director
(
DirectorlD int IDENTITY(1,1) NOT NULL,
Director_FirstName varchar(20),
Director_LastName varchar(25),
CONSTRAINT Director_PK PRIMARY KEY (DirectorlD)
)
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'Star')
DROP TABLE Star
CREATE TABLE Star
(
StarlD int IDENTITY(1,1) NOT NULL,
Star_FirstName varchar(20),
Star_LastName varchar(20),
CONSTRAINT Star_PK PRIMARY KEY (StarlD)
)
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'Genre')
DROP TABLE Genre
CREATE TABLE Genre
(
GenrelD int IDENTITY(1,1) NOT NULL,
Genre varchar(28),
CONSTRAINT Genre_PK PRIMARY KEY (GenrelD)
)
IF EXISTS (SELECT 1 FROM sys.tables WHERE name = 'Films')
DROP TABLE Films
CREATE TABLE Films
(
FilmslD int IDENTITY(1,1) NOT NULL,
Title varchar(49),
Rating NUMERIC(3,1),
DirectorID int,
StarlD int,
GenrelD int,
CONSTRAINT FilmslD_PK PRIMARY KEY (FilmslD)
)
ALTER TABLE Films
ADD CONSTRAINT fkl
FOREIGN key(DirectorID) REFERENCES Director(DirectorID);
ALTER TABLE Films
ADD CONSTRAINT fk2
FOREIGN key(StarlD) REFERENCES Star(StarlD);
ALTER TABLE Films
ADD CONSTRAINT fk3
FOREIGN key(GenrelD) REFERENCES Genre(GenrelD);
Error:
Msg 2714, Level 16, State 6, Line 6
There is already an object named 'Director' in the database.
Msg 3726, Level 16, State 1, Line 4
Could not drop object 'Director' because it is referenced by a FOREIGN KEY constraint.
My code part 1
My code part 2
Could not drop object 'Director' because it is referenced by a FOREIGN KEY constraint.
From the above error we know that the table ' Director' is referenced by Foreign Key Constraint. first, we need to drop that foreign keys then drop the table.
With help of following query, you can get foreign key constraint names and the referencing table names
SELECT name AS 'Foreign Key Constraint Name',
OBJECT_SCHEMA_NAME(parent_object_id) + '.' + OBJECT_NAME(parent_object_id) AS 'Child Table'
FROM sys.foreign_keys
WHERE OBJECT_SCHEMA_NAME(referenced_object_id) = 'schemaname' AND OBJECT_NAME(referenced_object_id) = 'tablename'
Now you can alter the child table and drop the constraint
ALTER TABLE childtable DROP CONSTRAINT fkconstraint;
After dropping all foreign key constraint for table, you can now drop the table by
Drop table tablename
Also refer this SO Thread answer by marc_s
create table school_student(
id int not null,
name varchar(20),
DOB Date,
Address varchar(50),
phone_no int,
primary key(id)
);
need to update the primary key column to auto increment in sql
alter table school_student alter column id int not null identity(5,1) primary key
i am getting below error,
Incorrect syntax near the keyword 'identity'.
Thanks Mayur Sawant for your reply from other post :) Its helped to drop the primary and foreign key .
Reference to his post :
Usage of Alter command to drop Primary key and Foreign Key
First of all you need to find the constraint name related to the Primary and Foreign keys. Then you need to use these constraint names while dropping the keys.
select *
from
information_schema.key_column_usage
where
table_name = 'my_table'
From the above query you will be able to find the constraint names.
Now use the below syntax to drop the keys.
ALTER TABLE tablename DROP CONSTRAINT constraint name
I built a big database with many tables. After that I forgat to add "delete on cascade". How do I add the "delete on casade" on the specific columns I want ?
For example:
create table Users
(
ID char(9) primary key check (ID like replicate('[0-9]',9)),
firstName nvarchar(20) not null,
)
And
create table Applications
(
name nvarchar(20) primary key,
establishDate date not null
)
How do I alter this table-registered to, so that when I delete an app or users it deletes the rows that has this value?
create table RegisteredTo
(
userID char(9) references Users(ID),
ApplicationName nvarchar(20) references Applications(name),
primary key(userID, ApplicationName)
)
I tried something like that - but I got errors.
alter table RegisteredTo
ALTER COLUMN applicationName references Applications(name) ON DELETE CASCADE
nvarchar(20)
You need to add a FOREIGN CONSTRAINT and ON DELETE CASCADE:
ALTER TABLE RegisteredTo
ADD CONSTRAINT FK_RegisteredTo_Users FOREIGN KEY (userID) REFERENCES Users(ID) ON DELETE CASCADE;
ALTER TABLE RegisteredTo
ADD CONSTRAINT FK_RegisteredTo_Applications FOREIGN KEY (ApplicationName) REFERENCES Applications(name) ON DELETE CASCADE;
the table was built as follow
create table schema1.detail(
ornum char(6) foreign key references schema1.menu(ornum),
num int,
pdname char(20),
price money check(price>0) default null,
amount int check(amount>0) not null,
primary key (ornum,num)
)
and I want to redefine the field 'amount' as amount>0 and amount<=1000 not null
but I don't know how to do it.
Well, if you already had data in your table you would have needed to keep it so you would have needed to first find out the name of the constraint (since your create script does not provide names to the constraints, SQL Server does it automatically for you), then drop the constraint and create a new one.
To do that, you would need to do something like this to find out the name of the constraints in your table:
SELECT TABLE_NAME,
COLUMN_NAME,
CHECK_CLAUSE,
cc.CONSTRAINT_SCHEMA,
cc.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS cc
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE c
ON cc.CONSTRAINT_NAME = c.CONSTRAINT_NAME
WHERE TABLE_NAME = 'detail'
AND cc.CONSTRAINT_SCHEMA = 'schema1'
ORDER BY CONSTRAINT_SCHEMA,
TABLE_NAME,
COLUMN_NAME
Then you need to drop the constraint and recreate it:
ALTER TABLE dbo.detail
DROP CONSTRAINT <constraint name> -- you got from the query above
ALTER TABLE detail
ADD CONSTRAINT CK_detail_amount CHECK(amount>0 AND amount<1000)
However, since this is a brand new table, I would suggest drop the table all together and re-create it, this time with proper names for the constraints:
drop table schema1.detail;
create table schema1.detail (
ornum char(6),
num int,
pdname char(20),
price money null, -- there is no need for the default keyword here...
amount int check(amount>0) not null,
constraint PK_detail primary key (ornum,num),
constraint FK_detail_menu foreign key (ornum) references schema1.menu(ornum),
constraint CK_detail_price check(price>0),
constraint CK_detail_amount check(amount>0 and amount <1000)
);
It's best practice to give your constraints meaningful names.
UPDATED
alter table schema1.detail drop constraint [yourConstraintName] ;
alter table schema1.detail add constraint [yourConstraintName] check (amount>0 and amount < 1000)
check constraint like "fieldname BETWEEN 0 and 1000"
or
amount int check (amount>0 AND amount <1000) not null,
I have simple table creating script in Postgres 9.1. I need it to create the table with
2-attributes PK only if it does not exist.
CREATE TABLE IF NOT EXISTS "mail_app_recipients"
(
"id_draft" Integer NOT NULL,
"id_person" Integer NOT NULL
) WITH (OIDS=FALSE); -- this is OK
ALTER TABLE "mail_app_recipients" ADD PRIMARY KEY IF NOT EXISTS ("id_draft","id_person");
-- this is problem since "IF NOT EXISTS" is not allowed.
Any solution how to solve this problem? Thanks in advance.
You could do something like the following, however it is better to include it in the create table as a_horse_with_no_name suggests.
if NOT exists (select constraint_name from information_schema.table_constraints where table_name = 'table_name' and constraint_type = 'PRIMARY KEY') then
ALTER TABLE table_name
ADD PRIMARY KEY (id);
end if;
Why not include the PK definition inside the CREATE TABLE:
CREATE TABLE IF NOT EXISTS mail_app_recipients
(
id_draft Integer NOT NULL,
id_person Integer NOT NULL,
constraint pk_mail_app_recipients primary key (id_draft, id_person)
)
You can try to DROP it before creating it (DROP has the IF EXISTS clause):
ALTER TABLE mail_app_recipients DROP CONSTRAINT IF EXISTS mail_app_recipients_pkey;
ALTER TABLE mail_app_recipients ADD CONSTRAINT mail_app_recipients_pkey PRIMARY KEY ("id_draft","id_person");
Note that this require that you give a name to the primary key constraint - in this example mail_app_recipients_pkey.