I have a table that has primary key on first column, but when I see the data available of this table, I find that records are repeated include primary key data. I want to know how can it be possible? Does primary column has repeated data in SQL Server 2008?
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[DemoTbl](
[ProcedureId] [int] NOT NULL,
[ProcedureName] [nvarchar](100) NOT NULL,
[VersionNo] [char](5) NULL,
[PublishDate] [datetime] NULL,
[PublishUser] [varchar](50) NULL,
[SpecialtyId] [int] NOT NULL,
[ProcedureNumber] [varchar](20) NULL,
[PowerpointName] [nvarchar](100) NULL,
[Duration] [int] NOT NULL,
[LanguageId] [int] NOT NULL,
[TierId] [smallint] NOT NULL,
[PrintPdf] [bit] NULL,
[PresentationModeId] [tinyint] NULL,
CONSTRAINT [pk_DemoTbl] PRIMARY KEY CLUSTERED
(
[ProcedureId] ASC,
[LanguageId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[DemoTbl] WITH CHECK ADD FOREIGN KEY([PresentationModeId])
REFERENCES [dbo].[DemoTbl] ([PresentationModeId])
GO
ALTER TABLE [dbo].[DemoTbl] WITH CHECK ADD CONSTRAINT [FK_DemoTbl_Specialty] FOREIGN KEY([SpecialtyId])
REFERENCES [dbo].[Specialty] ([SpecialtyId])
GO
ALTER TABLE [dbo].[DemoTbl] CHECK CONSTRAINT [FK_DemoTbl_Specialty]
GO
ALTER TABLE [dbo].[DemoTbl] WITH CHECK ADD CONSTRAINT [FK_DemoTbl_TierMaster] FOREIGN KEY([TierId])
REFERENCES [dbo].[TierMaster] ([TierId])
GO
ALTER TABLE [dbo].[DemoTbl] CHECK CONSTRAINT [FK_DemoTbl_TierMaster]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_CreationDate] DEFAULT (getdate()) FOR [CreationDate]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_ModifiedDate] DEFAULT (getdate()) FOR [ModifiedDate]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_IsActive] DEFAULT ((1)) FOR [IsActive]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_LanguageId] DEFAULT ((1)) FOR [LanguageId]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF_DemoTbl_ManageContent] DEFAULT ('false') FOR [ManageContent]
GO
ALTER TABLE [dbo].[DemoTbl] ADD CONSTRAINT [DF__Procedure__Print__1B14C01D] DEFAULT ((1)) FOR [PrintPdf]
GO
No, it is not possible in SQL Server to insert records that have duplicate values in the Primary Key.
It is not possible to have more than one row in the same table with the same primary key (PK).
If you are doing a SELECT and getting more than one row with the same PK could be because:
That table actually does not have a PK, maybe it was not properly created. You can check this by doing the following (it should return the PK column(s)):
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'TableName' AND COLUMN_KEY='PRI';
The SELECT statement is not correct. Maybe you are selecting from two or more tables and you are not relating them correctly.
To clarify, you can do the following:
1- Create a new table:
CREATE TABLE IF NOT EXISTS `Customer` (
`id` int(4),
`name` varchar(20),
`surname` varchar(40),
`phone` int(9),
PRIMARY KEY (`id`)
) ENGINE=INNODB;
Now you have a new table for storing customers identified by an ID.
2- Let's add some customers:
INSERT INTO Customer VALUES(111, 'John', 'White', 123456789),
(222, 'Bianca', 'Williams', 987654321),
(333, 'Mikel', 'Peterson', 421345642),
(444, 'Jolene', 'Gomez', 948113552);
3- If you try to insert a customer with an existing PK (id) you will get an error:
INSERT INTO Customer VALUES (222, 'Paul', 'Brown', 123412345);
4- In order to check the final table, you can do the following select:
SELECT * FROM Customer;
No it is not possible to have duplicate primary keys if the primary key constraint has been set to True.
Further to prevent duplicate primary keys set the Identity Specification to True
If this table is an intermediate table in a many to many connection the original columns are foreign keys and able to accept many instances of the same prodId(the whole point of the exercise). If someone then slams a PK on that column then no more duplicates can be added but if you query it the table will still return the original stuff in this guys screenshot.
This scenario can be seen in the Northwind sample database between Products and orders (OrderDetails table has composite PK on OrderID, ProdID but still shows duplicates of both). The PK was added afterwards, after data had been added.
The intermediate table is a link between the Many-to-Many tables and in general doesn't need a PK. Normalization 101.
For PK Constraint it create a Unique Index (Clustered / non Clustered ) on defined PK. If we disable indexes before loading that include PK Unique Index as well than we can insert duplicate PK in the column because the PK constraint is disabled. So while disabling Indexes please avoid PK index not be disable "is_primary_key=0 to disable all other indexes"
Tested -> it's possible if we create a primary key with nonclustered index. If we disable this index we will be able to insert duplicated record then. But - it won't be possible to enable (rebuild) the index back with duplicated values on primary key
Related
I have a database in SQL Server, where I have one table for customers, and each customer can have multiple bookings, but a booking can belong only to one customer. The point is that I have written an API and then a client side app using WPF, but I just noticed that I cannot delete a customer without actually previously deleting the associated bookings with that customer. My T-SQL looks like this roughly:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Customer](
[Id] [int] IDENTITY(1,1) NOT NULL,
[FullName] [nvarchar](50) NOT NULL,
[DateOfBirth] [date] NOT NULL,
[Phone] [nvarchar](20) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
))
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Booking](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Amount] [decimal](10,2) NOT NULL,
[CustomerId] [int] NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
))
ALTER TABLE [dbo].Booking WITH CHECK ADD CONSTRAINT [FK_Booking_Customer] FOREIGN KEY([CustomerId])
REFERENCES [dbo].[Customer] ([Id])
GO
ALTER TABLE [dbo].[Booking] CHECK CONSTRAINT [FK_Booking_Customer]
GO
Then, I have a delete stored procedure defined like this:
CREATE PROCEDURE DeleteCustomer
#Id int
AS
BEGIN
SET NOCOUNT ON;
DELETE FROM [dbo].[Customer]
WHERE Id = #Id
END
GO
But as I said I cannot delete a customer that has existing bookings. One way is surely to use CASCADE DELETE, but I don't want also the bookings to be deleted if the customer is deleted. Any idea how to overcome the problem or any workarounds?
The options I see are:
Make the foreign key column [CustomerId] nullable, and then use on delete set null
Use a soft delete on the Customer table, e.g. a bit column such as IsActive or IsDeleted.
Disable the foreign key: alter table [dbo].Booking nocheck constraint [FK_Booking_Customer]
Drop the foreign key.
In most situations I would implement the soft delete option.
Is there any way to drop a table having primary key and referenced by foreign key on another table? I know, If I will try to write a simple DROP statement then SSMS will throw me an exception saying
Msg 3726, Level 16, State 1, Line 1
Could not drop object 'dbo.Dept' because it is referenced by a FOREIGN KEY constraint.
May be the answer is simply NO but, I am looking for any work around as recently I was asked this in a Interview.
You have to drop the CONSTRAINT on the (child) table. That keeps the child table, but breaks the 'link' to the parent table.
Which is why I like to name my constraints. ("FK_EmployeeToDepartment" in this case).
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Employee]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN DROP TABLE [dbo].[Employee]
END
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[Department]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
BEGIN DROP TABLE [dbo].[Department]
END
CREATE TABLE [dbo].[Department](
[DepartmentUUID] [uniqueidentifier] NOT NULL,
[DepartmentName] [nvarchar](80) NULL,
[CreateDate] [datetime] NOT NULL
)
ALTER TABLE dbo.[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED ([DepartmentUUID])
GO
ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE ([DepartmentName])
GO
CREATE TABLE [dbo].[Employee] (
[EmployeeUUID] [uniqueidentifier] NOT NULL,
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeUUID)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT FK_EmployeeToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/* this will fail here */
--DROP TABLE [dbo].[Department]
GO
/* drop the constraint */
ALTER TABLE [dbo].[Employee] DROP CONSTRAINT FK_EmployeeToDepartment
GO
/* now it will work */
DROP TABLE [dbo].[Department]
GO
Drop the referenced table first and then parent table. That's why while creating reference you should choose ON DELETE CASCADE and/or ON UPDATE CASCADE.
It's purposefully throwing that error and stopping you from committing the mistake of making referenced table Orphan/Zombie.
If you really intend to drop a table that's referenced by a foreign key constraint, then the foreign key constraint is no longer meaningful, right? Drop the foreign key constraint first, then drop the table.
create table foo (
foo_id integer primary key
);
create table bar (
bar_id integer not null,
foo_id integer not null,
constraint bar_foo_id_fkey
foreign key (foo_id)
references foo (foo_id),
primary key (bar_id, foo_id)
);
drop table foo; -- Results in an error because of the foreign key constraint.
alter table bar
drop constraint bar_foo_id_fkey;
drop table foo; -- Drops table "foo".
You might still have work to do regarding existence of the column "bar"."foo_id", and regarding the primary key in "bar".
I have one member table structure in SQL Server:
member_table
memberid name address email
111 aaa IND a#a.com
222 bbb UK b#b.com
Now I want to give such facility that one member can follow as many other members. How can I do that?
Should I create a new table? Should I use any flags?
I'm thiking to create a new table and give Member table
You can create another table consisting of two attributes (member_id, follows_member_id)
This table keeps records of each member following other members. Both attributes reference your members table. This is a standard approach in creating a many-many relation as it is normalized. read more
I would create a junction table with a key on both member_ids to ensure there is at most 1 row.
I try to not cater to YGWITs (your gonna want it), but it seems a subscription table would call for some additional metadata such as the date the subscription starts or the last access date to know if there is new activity.
I would end up with something like this:
CREATE TABLE [dbo].[member_subscription](
[member_id] [int] NOT NULL,
[target_member_id] [int] NOT NULL,
[date_created] [datetime] NOT NULL,
[date_last_visit] [datetime] NULL,
CONSTRAINT [PK_member_subscription] PRIMARY KEY CLUSTERED
( -- key on both member_id fields
[member_id] ASC,
[target_member_id] ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
-- Foreign key contrain for member_id
ALTER TABLE [dbo].[member_subscription] WITH CHECK ADD CONSTRAINT [FK_member_subscription_member] FOREIGN KEY([member_id])
REFERENCES [dbo].[member] ([member_id])
GO
ALTER TABLE [dbo].[member_subscription] CHECK CONSTRAINT [FK_member_subscription_member]
GO
-- Foreign key contrain for target_member_id
ALTER TABLE [dbo].[member_subscription] WITH CHECK ADD CONSTRAINT [FK_member_subscription_target_member] FOREIGN KEY([target_member_id])
REFERENCES [dbo].[member] ([member_id])
GO
ALTER TABLE [dbo].[member_subscription] CHECK CONSTRAINT [FK_member_subscription_target_member]
GO
-- Default value for date_created
ALTER TABLE [dbo].[member_subscription] ADD CONSTRAINT [DF_member_subscription_datecreated] DEFAULT (getdate()) FOR [date_created]
GO
I finally created a table employee which contains a column empid that is a computed column and this column is primary key also.
It is a self referencing table, the column managerid references back to itself.
But now when I am saving the table after adding some more columns, I get an error
'Registration' table
Unable to create index 'PK_Registration'.
Cannot define PRIMARY KEY constraint on nullable column in table 'Registration'.
Could not create constraint. See previous errors.
but my table working perfectly ....
I want to work in the table graphically not coding every time I make a change
I cannot do it in graphically cause of this error there are 100 tables I dont like to do it coding it is very irritating
I want to do it in graphically in SQL Server 2008 Management Studio is it possible?
This is my table
CREATE TABLE [dbo].[Registration](
[empid] AS ('Sale_'+CONVERT([varchar](50),[id],(0))) PERSISTED NOT NULL,
[id] [int] IDENTITY(900000,1) NOT NULL,
[First_Name] [varchar](40) NULL,
[Last_Name] [varchar](40) NULL,
[Address] [varchar](40) NULL,
[E_Mail] [varchar](40) NULL,
[Country] [varchar](40) NULL,
[Mobile_No] [varchar](40) NULL,
[Designation] [varchar](40) NULL,
[managerID] [varchar](55) NULL,
CONSTRAINT [PK_Registration] PRIMARY KEY CLUSTERED
(
[empid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Registration] WITH CHECK ADD CONSTRAINT [FK_Registration_Registration] FOREIGN KEY([managerID])
REFERENCES [dbo].[Registration] ([empid])
GO
ALTER TABLE [dbo].[Registration] CHECK CONSTRAINT [FK_Registration_Registration]
GO
You could just not use empid as the primary key.
Use id as the primary key.
using "[int] IDENTITY" as the primary key of a table is the most common way of doing primary keys anyway.
The primary key and clustered index will control the storage.
I cannot see any benefit from using empid as the primary key.
Just make empid a computed column. For queries, SQL server will see that it is computed column and it uses just the primary key. SQL server will then use just the primary key on its queries.
I have a Microsoft SQL Database with 2 tables: dog and cat.
"dog" table has a primary key column called "food", which is related to a column called "food" as well in the "cat" table, which acts as the foreign key.
The relationship between the tables has an "on delete cascade" rule set, so when I delete a row from "dog" table, the relveant rows from "cat" table should be deleted as well.
But the rows in "cat" table do net get deleted, they stay. I use the Microsoft SQL Database manager to delete the row in "dog" table.
Any idea why this happens? do I need to use a special delete sql command to delete a row in this manner?
//edit
the script for the tables is:
USE [VELES]
GO
/****** Object: Table [dbo].[Periods] Script Date: 01/18/2011 14:52:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Periods](
[PeriodID] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
[PeriodName] [nvarchar](50) COLLATE Hebrew_CS_AS NULL,
[PeriodStartDate] [smalldatetime] NOT NULL,
[PeriodEndDate] [smalldatetime] NOT NULL,
CONSTRAINT [PK_Periods] PRIMARY KEY CLUSTERED
(
[PeriodID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
USE [VELES]
GO
/****** Object: Table [dbo].[Exams] Script Date: 01/18/2011 14:55:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Exams](
[ExamID] [int] IDENTITY(1,1) NOT NULL,
[ExamUserID] [char](7) COLLATE Hebrew_CS_AS NOT NULL,
[ExamBase] [tinyint] NOT NULL,
[ExamUserTimesAccessed] [tinyint] NULL,
[ExamMaxTimesToOpen] [tinyint] NOT NULL,
[ExamUserLastTimeOpened] [datetime] NULL,
[ExamUserLastTimeFinished] [datetime] NULL,
[ExamTimeToFinish] [int] NOT NULL,
[ExamPassGrade] [int] NOT NULL,
[ExamPeriod] [int] NOT NULL,
[ExamUserRank] [tinyint] NULL,
CONSTRAINT [PK_Exams] PRIMARY KEY CLUSTERED
(
[ExamID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
USE [VELES]
GO
ALTER TABLE [dbo].[Exams] WITH CHECK ADD CONSTRAINT [FK_Exams_Bases] FOREIGN KEY([ExamBase])
REFERENCES [dbo].[Bases] ([BaseID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Exams] WITH NOCHECK ADD CONSTRAINT [FK_Exams_Periods] FOREIGN KEY([ExamPeriod])
REFERENCES [dbo].[Periods] ([PeriodID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Exams] WITH NOCHECK ADD CONSTRAINT [FK_Exams_Users] FOREIGN KEY([ExamUserID])
REFERENCES [dbo].[Users] ([UserID])
ON UPDATE CASCADE
ON DELETE CASCADE
NOT FOR REPLICATION
GO
ALTER TABLE [dbo].[Exams] CHECK CONSTRAINT [FK_Exams_Users]
GO
ALTER TABLE [dbo].[Exams] WITH CHECK ADD CONSTRAINT [UserRanks_Exams_FK1] FOREIGN KEY([ExamUserRank])
REFERENCES [dbo].[UserRanks] ([RankID])
ON UPDATE CASCADE
ON DELETE CASCADE
I've solved the problem.
In the relationship window, there was an option called Enforce Foreign Key Constraint, which was set to "No".
I set it to "Yes" and now row deletion works well.
Can you show your table structure more concretely?
It sound like you have the PK/FK the wrong way around.
Deleting the FK part (child) does not do anything to the PK record (parent).
Only when you delete the PK records does it cascade to the child records that link to it.
For people using SQL Server Management Studio:
I've absolutely seen cases where the UI has got out of sync with the DB, even if it you refreshed the keys list or opened a completely new instance.
For my case I have an Order which has DiscountedItem child items.
The way to check if things are out of sync is to right click on FK_DiscountedItem_Order and select Script Key as CREATE To Clipboard and then examine what you get :
You should get something like this :
ALTER TABLE [dbo].[DiscountedItem]
WITH NOCHECK
ADD CONSTRAINT [FK_DiscountedItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([OrderId])
ON DELETE CASCADE; --should be seeing this!
ALTER TABLE [dbo].[DiscountedItem]
CHECK CONSTRAINT [FK_DiscountedItem_Order];
Where you can clearly see DELETE CASCADE.
If you get something like the following, then the cascade rule isn't actually active despite what the UI may say :
ALTER TABLE [dbo].[DiscountedItem]
WITH CHECK
ADD CONSTRAINT [FK_DiscountedItem_Order] FOREIGN KEY([OrderId])
REFERENCES [dbo].[Order] ([OrderId]);
I just deleted it (had to actually delete it twice) and recreated it to get the correct SQL.
You may need to run something like this to check for 'orphaned' child rows :
select * from DiscountedItem
where DiscountedItem.orderid not in (select orderid from [order])
And then if it is safe to do so :
delete from DiscountedItem
where DiscountedItem.orderid not in (select orderid from [order])
Why did this happen?
I just added the constraint and immediately got a foreign key error because I had orphaned rows. Something then got confused and it thought cascade was enabled.
So before creating a new constraint in the UI I recommend you always check first for orphaned rows. You will have to delete them anyway if they exist.
Are you sure the column food in dog is the primary key of dog? If you have a table called food, then it's column food should be the primary key of food and a foreign key of dog (and cat as well). Then with on delete cascade deletions on food will cause the corresponding rows on dog and cat to be deleted.
If the cat table is the key for the foreign key, then deleting a row from dog will not delete a row from cat, rather it would work the other way around.
This seams to work just fine.
delete from Periods where PeriodID = 1
will delete one row from Periods and all rows from Exams that have ExamPeriod = 1