How to redefine the constraint in a field? - sql

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,

Related

It is difficult to code in Microsoft SQL Server due to foreign keys and constraints

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

Need help in updating primary key field

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

Add primary key to PostgreSQL table only if it does not exist

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.

Sybase constraint with foreign key and conditional check against foreign table column value

Is it possible on Sybase to define a constraint(s) which require a column to be a foreign key and also satisfy a condition based on the value of a foreign column, e.g. in the below example tables could a constraint be created on the "product" table such that "product.code is a foreign key of a brand.code which has valid=1"?
CREATE TABLE brand (
code char(8) NOT NULL,
valid int NOT NULL,
rowid numeric(10,0) IDENTITY,
CONSTRAINT brand_pk PRIMARY KEY (code),
CONSTRAINT valid_check CHECK (valid IN (0,1))
)
CREATE TABLE product (
code char(8) NOT NULL,
CONSTRAINT product_pk PRIMARY KEY (code)
)
I think it's best to change the structure just a little bit.
CREATE TABLE brand (
code char(8) NOT NULL,
valid int NOT NULL,
rowid numeric(10,0) IDENTITY,
CONSTRAINT brand_pk PRIMARY KEY (code),
-- The following UNIQUE constraint lets the pair of values be the target of
-- a foreign key reference.
CONSTRAINT brand_is_valid UNIQUE (code, valid),
CONSTRAINT valid_check CHECK (valid IN (0,1))
);
CREATE TABLE product (
code char(8) NOT NULL,
valid int NOT NULL,
-- The column "code" is a PK in the referenced table, so this still works. It's
-- a 1:0 or 1:1 relationship.
CONSTRAINT product_pk PRIMARY KEY (code),
-- The next constraint requires a unique constraint on the pair of
-- columns in the table "brand". By itself, it references every row
-- in "brand". That's too many rows.
CONSTRAINT product_fk FOREIGN KEY (code, valid)
REFERENCES brand (code, valid),
-- But this constraint restricts the foreign key references to only those
-- rows that have valid = 1 in the table "brand".
CHECK (valid = 1)
);
In order to bypass the creation of a foreign-key based on the "valid" condition, you will need to modify your table design and create a trigger to set the product.code = NULL. Pardon my syntax (I haven't coded Sybase for a while), but this is the general idea:
Add a new column to serve as the primary key since we will need to set product.code = NULL when valid=0:
CREATE TABLE product (
rowid int identity primary key,
code char(8) NULL,
CONSTRAINT brand_fk FOREIGN KEY (code) REFERENCES brand(code)
)
Then create a trigger similar to this one:
create trigger FK_WhenValid
on product
for insert
AS
IF (SELECT COUNT(*) FROM brand b inner join inserted i on b.code = i.code AND b.valid=0 ) > 0
BEGIN
UPDATE product SET code = NULL WHERE code in (SELECT i.code from brand b join inserted i on b.code = i.code and b.valid = 0)
END
Note: this trigger only supports product insertions. If "valid" can change, another approach is required.
You could also implement the foreign key as a trigger instead of a declarative constraint and only set product.code = inserted.code when valid = 1

How do I create a foreign key in SQL Server?

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)