Cannot define PRIMARY KEY constraint on nullable column in table - sql

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.

Related

create a constraint on a column, but only for a part of the data

I want to create a constraint on a column, but only for a part of the data.
The situation is this: we have all the values for all dropdowns in one table. To separate them we have a discriminator called dropdowntype.
Now I want to create a constraint, but it has to take the dropdowntype into account.
The constraint is: dropdowns can have a default value. There is only zero or one record allowed, per dropdowntype, which has the value true for isdefault.
So there can be multiple records with the value true for isdefault, but they should all have a different value for dropdowntype.
EDIT:There are however multiple values allowed for a given dropdowntype with the value false.
Is this possible to do?
(then as a bonus, I would also like to put a constraint on another nullable column, that all values for that column are either null or have a value, again for a given dropdowntype. But maybe when the first question is answered, I'll figure out how to do this one myself.)
Table:
CREATE TABLE [dbo].[DropDownValues](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDefaultValue] [bit] NOT NULL,
[Description] [nvarchar](1000) NULL,
[IsOtherItem] [bit] NOT NULL,
[Dropdowntype] [tinyint] NOT NULL,
CONSTRAINT [PK_ddv] PRIMARY KEY CLUSTERED
(
[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]
To answer question 1, you want a compound unique key on dropdowntype and isdefault. Pseudo code:
CREATE UNIQUE NONCLUSTERED INDEX idx_yourcolumn_notnull
ON YourTable(dropdowntype, isdefault)
WHERE isdefault IS NOT NULL;
You can do the same for the 2nd part of your question. They key is the WHERE isDefault IS NOT NULL, ths allows you to create a unique constraint on a nullable column.

Still FK conflict, even after investigation

4.857 million rows went through the flow OK, and only 38.000 rows sent to error output. This due to a FK conflict. ---> "The INSERT statement conflicted with the FOREIGN KEY constraint "FK_FactTransactions_DimCustomer".
The conflict occurred in database "", table "dbo.DimCustomer", column 'CustomerNr'.".
My problem is, after some investigation, i can't identify any conflict in the primary table dbo.dimcustomer.
Lets take Mid(Named CustomerNr in the DB) "60534658" for an example and let us see.
Picture NR
1: This is a data-view draft of some of the rows that got sent to error output for analysis.
2: This is the table where its supposed to insert, notice that rows with the same CustomerNr already exists, because some rows of the same CustomerNr, for a strange reason, got inserted while others did not
3: And last. This is the actual primary table(Customer table), where the Mid(CustomerNr) reference clearly exists!
Am i missing something here? why is it still in conflict?
ty for any answers!
TABLE STRUCTURE:
CREATE TABLE [dbo].[DimCustomer](
[CustomerNr] [int] NOT NULL,
[CustomerID] [int] NULL,
[GeographyKey] [int] NULL,
[OrgNum] [nvarchar](50) NULL,
[CustomerName] [nvarchar](255) NULL,
[Adress] [nvarchar](255) NULL,
[ZipCode] [nvarchar](255) NULL,
[MCC_Code] [float] NULL,
CONSTRAINT [PK_Dim.Customer_1] PRIMARY KEY CLUSTERED
(
[CustomerNr] 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
ALTER TABLE [dbo].[DimCustomer] WITH CHECK ADD CONSTRAINT [FK_DimCustomer_DimGeography] FOREIGN KEY([GeographyKey])
REFERENCES [dbo].[DimGeography] ([GeographyKey])
GO
ALTER TABLE [dbo].[DimCustomer] CHECK CONSTRAINT [FK_DimCustomer_DimGeography]
GO
CREATE TABLE [dbo].[FactTransactions](
[TransactionKey] [int] IDENTITY(1,1) NOT NULL,
[Reportdate] [date] NULL,
[CustomerNr] [int] NULL,
[SchemeID] [smallint] NULL,
[PriceType] [int] NULL,
[Count] [int] NULL,
[Amount] [float] NULL,
[Commission] [float] NULL,
[InterchangeFee] [float] NULL,
[Currency] [nvarchar](3) NULL,
[FeeType] [int] NULL,
CONSTRAINT [PK_FactTransactions] PRIMARY KEY CLUSTERED
(
[TransactionKey] 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
ALTER TABLE [dbo].[FactTransactions] WITH CHECK ADD CONSTRAINT [FK_FactTransactions_DimCardScheme] FOREIGN KEY([SchemeID])
REFERENCES [dbo].[DimCardScheme] ([SchemeID])
GO
ALTER TABLE [dbo].[FactTransactions] CHECK CONSTRAINT [FK_FactTransactions_DimCardScheme]
GO
ALTER TABLE [dbo].[FactTransactions] WITH CHECK ADD CONSTRAINT [FK_FactTransactions_DimCustomer] FOREIGN KEY([CustomerNr])
REFERENCES [dbo].[DimCustomer] ([CustomerNr])
GO
ALTER TABLE [dbo].[FactTransactions] CHECK CONSTRAINT [FK_FactTransactions_DimCustomer]
GO
ALTER TABLE [dbo].[FactTransactions] WITH CHECK ADD CONSTRAINT [FK_FactTransactions_DimDate] FOREIGN KEY([Reportdate])
REFERENCES [dbo].[DimDate] ([Date])
GO
ALTER TABLE [dbo].[FactTransactions] CHECK CONSTRAINT [FK_FactTransactions_DimDate]
GO
ALTER TABLE [dbo].[FactTransactions] WITH CHECK ADD CONSTRAINT [FK_FactTransactions_DimPriceType] FOREIGN KEY([PriceType])
REFERENCES [dbo].[DimPriceType] ([PriceType])
GO
ALTER TABLE [dbo].[FactTransactions] CHECK CONSTRAINT [FK_FactTransactions_DimPriceType]
GO
Example error output line:
2015-05-01,60534658,1,1,57,484,5280,3000000000002,78,340000000000003,0,EUR,57,1
Maybe you have some FactTrancsactions pointing to a customer which doesn't exist.
Try this statement to check if there are some transaction pointing to the wrong customer. Each row returned by this statement will bounce if you create the foreign key.
SELECT ft.*
FROM dbo.FactTransactions as ft
LEFT JOIN dbo.DimCustomer as dc
ON ft.CustomerNr = dc.CustomerNr
WHERE dc.CustomerNr IS NULL

Why create a foreign key constraint that references the primary key of the same table from the primary key field

I inherited a SQL Server database that has a table with a primary key named RecordID. The table definition and the foreign key defined like this:
CREATE TABLE [dbo].[MyTable](
[RecordId] [int] IDENTITY(1,1) NOT NULL,
[FileName] [nvarchar](255) NOT NULL,
[Record] [nvarchar](255) NOT NULL,
[ErrorDescription] [nvarchar](255) NULL,
[ProcessDate] [datetime] NOT NULL,
CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED
(
[RecordId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[MyTable] WITH CHECK ADD CONSTRAINT [FK_MyTable_MyTable] FOREIGN KEY([RecordId])
REFERENCES [dbo].[MyTable] ([RecordId])
GO
ALTER TABLE [dbo].[MyTable] CHECK CONSTRAINT [FK_MyTable_MyTable]
GO
I could understand this if the foreign key referenced from a different field in the same table back to the primaray key field which would allow for a heirarchy, but in this case the two fields in the foreign key definition are exactly the same field. Is this just a mistake in the original definition of the table and foreign key? Or is there a real advantage somehow to this?
Thanks in advance for your time in replying.
Because the foreign key references itself, the check can never fail. That makes it, as a constraint, a no-op, so it is in every sense of the word, extraneous. Someone clearly made a mistake in creating the constraint.
I thought I might be missing something, so a quick check turned up with this: http://www.dotnetnuke.com/Resources/Forums/forumid/-1/postid/342163/scope/posts.aspx which reinforces my suspicion (user error). My most educated conclusion is that someone at some stage thought of creating a self-referencing (other column) table constraint, but in a wicked twist of confusion created this abomination.

Problem Setting Foreign Key

I am trying to set a foreign key relationship between an Order_Items table and Parts table. I want to link the parts to products in the Order_Items table via foreign key. I have no issues doing this with other tables.
Here is how the Order_Items table is defined:
CREATE TABLE [dbo].[Order_Items](
[order_id] [uniqueidentifier] NOT NULL,
[product_number] [varchar](50) NOT NULL,
[quantity_ordered] [int] NOT NULL,
[product_tested] [bit] NULL,
CONSTRAINT [PK_Order_Items] PRIMARY KEY CLUSTERED
(
[order_id] ASC,
[product_number] 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].[Order_Items] WITH CHECK ADD CONSTRAINT [FK_Order_Items_Orders] FOREIGN KEY([order_id])
REFERENCES [dbo].[Orders] ([order_id])
GO
ALTER TABLE [dbo].[Order_Items] CHECK CONSTRAINT [FK_Order_Items_Orders]
and Parts table:
CREATE TABLE [dbo].[Parts](
[part_number] [varchar](50) NOT NULL,
[product_number] [varchar](50) NOT NULL,
[part_description] [varchar](max) NULL,
[part_tested] [bit] NULL,
CONSTRAINT [PK_Parts_1] PRIMARY KEY CLUSTERED
(
[part_number] ASC,
[product_number] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I have tried setting the unique constraint on both product_number columns, but I still get the error message in SQL Server 2005 Management Studio Express as:
"The columns in table 'Order_Items' do not match an existing primary key or UNIQUE constraint"
Question: if [product_number] in your Parts table can be made unique by a unique constraint - why isn't it the primary key by itself??
My gut feeling: [product_number] in Parts isn't really unique - only the combination of (part_number, product_number), which is the primary key, really is unique.
If you can create a UNIQUE INDEX on the product_number column alone, you should be able to create the FK constraint - try this:
CREATE UNIQUE INDEX UIX01_Parts ON dbo.Parts(product_number)
ALTER TABLE dbo.Order_Items
ADD CONSTRAINT FK_OrderITems_Parts
FOREIGN KEY(product_number) REFERENCES dbo.Parts(product_number)
Does it work? If not - what error to you get, and where??
If that doesn't work, and only (part_number, product_number) is truly unique, then you need to reference both columns in your foreign key constraint:
ALTER TABLE dbo.Order_Items
ADD CONSTRAINT FK_OrderItems_Parts
FOREIGN KEY(part_number, product_number)
REFERENCES dbo.Parts(part_number, product_number)
and of course, this also means you need to have both those columns in your Order_Items table in order to be able to make the foreign key constraint work.
Just as a side note: having a compound primary key of two VARCHAR(50) columns and making that a clustered index on your Parts table is anything but optimal. If ever possible, try to make one or both of those "numbers" really a numeric type - e.g. an INT column. Or if that is not possible, think about having a surrogate PartID column (INT, IDENTITY) on your Parts table - that would make the FK constraint easier, too!
In order for this relationship to work, the Parts table cannot have composite key. In other words, you need to use product_number as the primary key since it is the column that they both have in common. You currently have part_number and product_number as your primary key.
Once you make that change, this statement will work:
ALTER TABLE [dbo].[Order_Items] WITH CHECK
ADD CONSTRAINT [FK_Order_Items_Parts] FOREIGN KEY([product_number])
REFERENCES [dbo].[Parts] ([product_number])
I ended up restructuring my entire database to get this to work and streamlined the table connections.

How do you add Foreign Key Relationships?

I'm working with an existing SQL 2005 database that was not implemented with FK relationships between tables. I tried to add the relationships with a database diagram and my application immediately blew up trying to edit or insert any data that is tied to the new FK.
dbo.person [person_id | firstname | lastname | dateofbirth]
dbo.campaign [campaign_id | campaign_description]
dbo.disposition [disposition_id | disposition_description]
dbo.person_campaigns [person_campaign_id | person_id | campaign_id | disposition_id]
The person_campaigns table is where a person, campaign, and disposition are tied together. Can you please provide the appropriate SQL syntax for adding the proper FK relationships between these entities?
EDIT
CREATE TABLE [dbo].[person_campaigns](
[person_campaigns_id] [int] IDENTITY(1,1) NOT NULL,
[person_id] [int] NOT NULL,
[d_campaign_id] [int] NOT NULL,
[d_physician_disposition_id] [int] NULL,
CONSTRAINT [PK_person_campaigns] PRIMARY KEY CLUSTERED
(
[person_campaigns_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
CREATE TABLE [dbo].[d_campaign](
[d_campaign_id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NULL,
[year] [int] NULL,
[isactive] [bit] NOT NULL,
CONSTRAINT [PK_d_campaign] PRIMARY KEY CLUSTERED
(
[d_campaign_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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[d_campaign] ADD CONSTRAINT [DF_d_campaign_isactive] DEFAULT ((1)) FOR [isactive]
GO
CREATE TABLE [dbo].[d_disposition](
[d_disposition_id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NULL,
[isactive] [bit] NOT NULL,
CONSTRAINT [PK_d_disposition] PRIMARY KEY CLUSTERED
(
[d_disposition_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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[d_disposition] ADD CONSTRAINT [DF_d_disposition_isactive] DEFAULT ((1)) FOR [isactive]
GO
CREATE TABLE [dbo].[person](
[person_id] [int] IDENTITY(1,1) NOT NULL,
[firstname] [varchar](30) NULL,
[lastname] [varchar](30) NULL,
[dateofbirth] [datetime] NULL
CONSTRAINT [PK__person__0BC6C43E] PRIMARY KEY CLUSTERED
(
[person_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
the easiest way to do it is through the database diagram editor; do them one at a time and save the diagram to affect the tables after each connection is made. If it "blows up" it is most likely because the tables contain foreign-key values that do not exist; you'll have to clean these up first.
If you have to add them after the table is created the syntax is
create table person (person_id int primary key
,firstname varchar(10)
, lastname varchar(10)
, dateofbirth varchar(10))
create table campaign (campaign_id int primary key
, campaign_description varchar(10))
create table disposition (disposition_id int primary key
,disposition_description varchar(10))
create table person_campaigns(person_campaign_id int
,person_id int, campaign_id int ,disposition_id int)
go
alter table person_campaigns add Constraint
fk_person_campaigns_person_id
Foreign Key (person_id) References person(person_id)
GO
alter table person_campaigns add Constraint
fk_person_campaigns_campaign_id
Foreign Key (campaign_id) References campaign(campaign_id)
GO
alter table person_campaigns add Constraint
fk_person_campaigns_disposition_id
Foreign Key (disposition_id) References disposition(disposition_id)
GO
Suppose I had two tables that should have had a foreign key but did not. The first thing to do is check to see if there will be a data problem if I set a foreign key.
something like the below code would get you the records in the child table that do not have a match in the parent table.
select t2.FKField, t2.PKfield from table2 t2
left join Table1 t1 on t2.fkfield = t1.pkfield
where t1.pkfield is null
Once you can see what is wrong with the existing data, then you need to create a way to fix it. The fix will vary depending on what data you have that has no relationship to the Parent table and what the tables represent. Suppose your parent table contained a VIN number for automobiles as the PK. If your child table contains the cars that were worked on by the shop, you would want to fix the issue by adding the nonexisting VINS to the primary table becasue you wouldn't want to lose the history of what was worked on. There are other structures where you might want to simply delete the records that don't match in child table because they are meaningless. In other circumstances you might want to update those records to some default value (perhaps a customer in the customer table called unknown). In still other circumstances, you might need to go to audit tables or backups to find the value of the PK that was deleted without the associated child records being deleted. The actual way to fix this problem is highly dependent on what the data is used for and how important it is to retain all historical records. Since you should never delete any record that might be related to a financial transaction for legal (and accounting) reasons, you need to be most careful with those.
After fixing all the data, then you run the code to create the FK constraint.
Since I don't have SQL Server on this PC and I don't memorize the syntax, the easiest thing to do is to create two new test tables, create TableA with an ID field, TableB with a field that is a FK of TableA.ID, and then script out TableB to see the ADD CONSTRAINT syntax. Do this using SQL Server Management Studio via a database diagram.
However, if you were able to successfully create the FKs in a data diagram, and you only can't add or update records, I believe something else is wrong. Script out the person_campaigns table and post the code.