UNIQUE Constraint For Columns On Different Tables - sql

I have three tables a,b,and c each with an int IDENTITY PK field that relates to the child table.
CREATE TABLE [dbo].[a]([aID] [int] IDENTITY(1,1) NOT NULL,[aCode] [varchar](20) NOT NULL,
CONSTRAINT [PK_a] PRIMARY KEY CLUSTERED([aID] 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].[b]([bID] [int] IDENTITY(1,1) NOT NULL,[aID] [int] NOT NULL, [bCode] [varchar](20) NOT NULL,
CONSTRAINT [PK_b] PRIMARY KEY CLUSTERED([bID] 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].[c]([cID] [int] IDENTITY(1,1) NOT NULL,[bID] [int] NOT NULL,[cCode] [varchar](20) NOT NULL,
CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED([cID] 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].[b] WITH CHECK ADD CONSTRAINT [FK_b_a] FOREIGN KEY([aID])
REFERENCES [dbo].[a] ([aID])
GO
ALTER TABLE [dbo].[b] CHECK CONSTRAINT [FK_b_a]
GO
ALTER TABLE [dbo].[c] WITH CHECK ADD CONSTRAINT [FK_c_b] FOREIGN KEY([bID])
REFERENCES [dbo].[b] ([bID])
GO
ALTER TABLE [dbo].[c] CHECK CONSTRAINT [FK_c_b]
GO
How do I create a CONSTRAINT that enforces a unique condition for a.aID, c.cCode?

If you are looking for a unique constraint over a combination of columns a.aID, c.cCode one way is to alter table c and add [aid] column to it and have a composite unique key.
ALTER TABLE [dbo].[c](
[cID] [int] IDENTITY(1,1) NOT NULL,
[bID] [int] NOT NULL,[cCode] [varchar](20) NOT NULL,
[cCode] [varchar](20) NOT NULL,
[aID] INT FOREIGN KEY REFERENCES [a]([aID]) NOT NULL,
CONSTRAINT uq_cCode_aid UNIQUE NONCLUSTERED (cCode,aID),
CONSTRAINT [PK_c] PRIMARY KEY CLUSTERED([cID] 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

You can add a unique constraint as follows:
ALTER TABLE [C] ADD CONSTRAINT [uc_C_cCode] UNIQUE NONCLUSTERED [cCode];
You cannot however enforce a constraint across tables, which is what it sounds like you are trying to do.
As for table A.aID, its a primary key, it will already have a unique constraint.

I found a way to get what I wanted (I think) using an indexed view. Please comment on if this seems appropriate. My tests so far conclude that it does work.
I created a view with schemabinding on joining c to a (going through b).
I created an clustered index to enforce unique on aID and cCode.
This allows me to not need to include aID within the c table but still enforces the unique constraint.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[vw.aIDcCode] WITH SCHEMABINDING
AS
SELECT dbo.a.aID, dbo.c.cCode
FROM dbo.a
INNER JOIN
dbo.b ON dbo.a.aID = dbo.b.aID
INNER JOIN
dbo.c ON dbo.b.bID = dbo.c.bID
GO
SET ARITHABORT ON
GO
SET CONCAT_NULL_YIELDS_NULL ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
SET ANSI_PADDING ON
GO
SET ANSI_WARNINGS ON
GO
SET NUMERIC_ROUNDABORT OFF
GO
CREATE UNIQUE CLUSTERED INDEX [IDX_Unique_aIDcCode] ON [dbo].[vw.aIDcCode]
([aID] ASC, [cCode] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY]
GO

Related

Violation of primary key after switch partition (stage>dbo)

Would someone help, please, to get rid of the error:
Violation of PRIMARY KEY constraint 'PK_stmp_tst1'. Cannot insert duplicate key in object 'dbo.stmp_tst'. The duplicate key value is (1).
which occurs after switch partition of the table.
Full SQL Script below:
I. Create 2 equal tables in different schemas:
CREATE TABLE dbo.stmp_tst(
[inn] [varchar](20) NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_stmp_tst] 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]
go
CREATE TABLE stage.stmp_tst(
[inn] [varchar](20) NULL,
[id] [bigint] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_stmp_tst] 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]
GO
II. Insert data into stage table.
insert into stage.stmp_tst (inn)
select '1111'
III. Switch-partition stage to dbo.
alter table stage.stmp_tst switch partition 1 to dbo.stmp_tst partition 1;
IV. Add data to dbo table.
insert into dbo.stmp_tst (inn)
select '1111'
V. We have the error:
Violation of PRIMARY KEY constraint 'PK_stmp_tst1'. Cannot insert
duplicate key in object 'dbo.stmp_tst'. The duplicate key value is
(1).
IV. Drop temporary tables:
drop table dbo.stmp_tst
drop table stage.stmp_tst
It can be solved by the query:
DBCC CHECKIDENT ('dbo.stmp_tst', RESEED);
but reseeding takes time.
Is it possible to do a switch-partition correctly without reseed?
Thank you.

The specified schema name either does not exist or you do not have permission to use it

I am trying to create replica of my database from SQL server to another.
For that I am generating script from original server and trying to run in another server. I've created database manually with the same name.
Here is the screenshot of original database
When I generate script, following script is created which I am trying in another server
USE [ContactsApp]
GO
/****** Object: Table [common].[BU] Script Date: 2/12/2016 3:02:29 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [common].[BU](
[ID] [int] IDENTITY(1,1) NOT NULL,
[IndustryID] [int] NOT NULL,
[BU] [varchar](50) NOT NULL,
[Code] [varchar](2) NOT NULL,
[Active] [bit] NOT NULL,
[CreatedBy] [uniqueidentifier] NOT NULL,
[CreateDate] [date] NOT NULL,
[CreateTime] [time](3) NOT NULL,
[ModifiedBy] [uniqueidentifier] NULL,
[ModifyDate] [date] NULL,
[ModifyTime] [time](3) NULL,
CONSTRAINT [PK_BU] 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],
CONSTRAINT [UK_BU_Code] UNIQUE NONCLUSTERED
(
[Code] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [UK_BU_Name] UNIQUE NONCLUSTERED
(
[BU] 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 [common].[BU] ADD CONSTRAINT [DF_BU_CreateDate] DEFAULT (CONVERT([date],getdate())) FOR [CreateDate]
GO
ALTER TABLE [common].[BU] ADD CONSTRAINT [DF_BU_CreateTime] DEFAULT (CONVERT([time],getdate())) FOR [CreateTime]
GO
ALTER TABLE [common].[BU] WITH CHECK ADD CONSTRAINT [FK_BU_Industry] FOREIGN KEY([IndustryID])
REFERENCES [common].[Industry] ([ID])
ON DELETE CASCADE
GO
ALTER TABLE [common].[BU] CHECK CONSTRAINT [FK_BU_Industry]
GO
When I try to run this script, I get following error
The specified schema name "common" either does not exist or you do
not have permission to use it.
I don't know what is the meaning of common here.Thanks
Your tables are 'grouped' (for want of better word) in schemas (google for it). You should run
CREATE SCHEMA common
And likewise for all other schemas.

How to set hierarchic foreign key through another table?

I am not sure if my title really explains the question, so I'll try an example:
Let's say I have:
1) region table: parent regions and subregions in the same table (link A)
2) product table: each product is linked to a single parent region (link B)
3) product_price table: lists the price of a product (C) in all sub regions of that product region (link D >>> the link in question).
(the diagram is showing only the relevant fields, there are a lot more data in region and product)
Is there a way to define the region->region_price key, to include only sub_region_id's of the parent_region in the product->region key??
Or, in the terms of the image, how do I make the D link to include only regions that are children [as in A] of the B & C link?
Hope you are getting my point...
Here are the real tables and links:
CREATE TABLE [dbo].[product](
[product_id] [int] NOT NULL,
[product_name] [nchar](10) NOT NULL,
[parent_region_id] [int] NOT NULL,
CONSTRAINT [PK_product] PRIMARY KEY CLUSTERED
(
[product_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]
CREATE TABLE [dbo].[product_price](
[product_id] [int] NOT NULL,
[sub_region_id] [int] NOT NULL,
[price] [decimal](18, 0) NOT NULL,
CONSTRAINT [PK_product_price] PRIMARY KEY CLUSTERED
(
[product_id] ASC,
[sub_region_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]
CREATE TABLE [dbo].[region](
[region_id] [int] NOT NULL,
[region_name] [nvarchar](50) NOT NULL,
[parent_region_id] [int] NULL,
CONSTRAINT [PK_region] PRIMARY KEY CLUSTERED
(
[region_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]
ALTER TABLE [dbo].[product] WITH CHECK ADD CONSTRAINT [FK_product_region] FOREIGN KEY([parent_region_id])
REFERENCES [dbo].[region] ([region_id])
ALTER TABLE [dbo].[product] CHECK CONSTRAINT [FK_product_region]
ALTER TABLE [dbo].[product_price] WITH CHECK ADD CONSTRAINT [FK_product_price_product] FOREIGN KEY([product_id])
REFERENCES [dbo].[product] ([product_id])
ALTER TABLE [dbo].[product_price] CHECK CONSTRAINT [FK_product_price_product]
ALTER TABLE [dbo].[product_price] WITH CHECK ADD CONSTRAINT [FK_product_price_region] FOREIGN KEY([sub_region_id])
REFERENCES [dbo].[region] ([region_id])
ALTER TABLE [dbo].[product_price] CHECK CONSTRAINT [FK_product_price_region]
ALTER TABLE [dbo].[region] WITH CHECK ADD CONSTRAINT [HK_region_region] FOREIGN KEY([parent_region_id])
REFERENCES [dbo].[region] ([region_id])
ALTER TABLE [dbo].[region] CHECK CONSTRAINT [HK_region_region]
I guess you are trying to enforce a business rule with a database rule, but they're not always the same. Instead, you can run validation querys in your code before inserting or updating, or you could implement a trigger that validates your rules or throws an error.

EF 6 Bridge Table Insert Not Working

I am still trying to learn how to use EF and running into a problem with my bridge table.
When I try to create a new Order with associated Resources, I get the following SQL error:
{"Violation of PRIMARY KEY constraint 'PK_Resource_Type'. Cannot insert duplicate key in object 'dbo.Resource_Type'. The duplicate key value is (2).\r\nThe statement has been terminated."}
Code Looks like this
ResourceType resource = new ResourceType();
resource.ID = 2;
resource.Name = "Van"
order.resourceType().Add(resource)
db.Orders.Add(order);
db.SaveChanges();
Tables look like this
--Order table
CREATE TABLE [dbo].[Orders](
[Order_ID] [int] IDENTITY(1,1) NOT NULL,
[OrdernName] [varchar](100) NOT NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED
(
[Order_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
--Resource Type table
CREATE TABLE [dbo].[Resource_Type](
[ResourceType_ID] [int] NOT NULL,
[ResourceType] [varchar] (30) NOT NULL
CONSTRAINT [PK_Resource_Type] PRIMARY KEY CLUSTERED
(
[ResourceType_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
--Resource Type To Order table
CREATE TABLE [dbo].[Resource_Type_Order](
[ResourceType_ID] [int] NOT NULL,
[Order_ID] [int] NOT NULL
CONSTRAINT [PK_Resource_Type_Order] PRIMARY KEY CLUSTERED
(
[ResourceType_ID] ASC,
[Order_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
ALTER TABLE [dbo].[Resource_Type_Order] WITH CHECK ADD CONSTRAINT FK_Order_Resource_Type_Order FOREIGN KEY([Order_ID])
REFERENCES [dbo].[Orders]([Order_ID])
GO
ALTER TABLE [dbo].[Resource_Type_Order] WITH CHECK ADD CONSTRAINT FK_Resource_Type_Order_Resource_Type FOREIGN KEY([ReosurceType_ID])
REFERENCES [dbo].[Resource_Type]([Resource_ID])
GO
Am I using the bridge table correctly? I want my bridge table to look like this, after I add an order (ID=1) with two resources (car ID=1 and van ID=2).

use two primary keys attribute from a table with different title

I got table "Functions" with Function_ID {PK} and I want another table "Hierarchy" with Hierarchy_ID {PK} which defines tree structure of functions so i need one Function_ID from Function table AS Parent_ID and one Function_ID AS Child. my question is how i can use two primary keys from another table to make it together as Foreign key
I am using SQL Server 2012 and the Management Studio
Many Thanks
Actually you just need to add a ParentFunction_ID column in the Functions table.
You don't need another table if your structure is indeed a tree.
Then make the ParentFunction_ID to be a FK to the same table Functions.
So ParentFunction_ID (FK) would be pointing to Function_ID (PK).
The only record which has ParentFunction_ID NULL would be the root of your tree.
Here is some sample code:
USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Functions](
[Function_ID] [int] IDENTITY(1,1) NOT NULL,
[FunctionCode] [varchar](max) NULL,
[ParentFunction_ID] [int] NULL,
CONSTRAINT [PK_Functions] PRIMARY KEY CLUSTERED
(
[Function_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].[Functions] WITH CHECK ADD CONSTRAINT [FK_Functions_Functions] FOREIGN KEY([ParentFunction_ID])
REFERENCES [dbo].[Functions] ([Function_ID])
GO
ALTER TABLE [dbo].[Functions] CHECK CONSTRAINT [FK_Functions_Functions]
GO
Name your Functions table a Function table. AFAIK using
plurals for table names is not really a good practice.
So you can do this.
--- 1 ---
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Function](
[Function_ID] [int] IDENTITY(1,1) NOT NULL,
[FunctionCode] [varchar](max) NULL,
CONSTRAINT [PK_Function] PRIMARY KEY CLUSTERED
(
[Function_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
--- 2 ---
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Hierarchy](
[ID] [int] IDENTITY(1,1) NOT NULL,
[ParentFunction_ID] [int] NULL,
[ChildFunction_ID] [int] NULL,
CONSTRAINT [PK_Hierarchy] 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]
GO
ALTER TABLE [dbo].[Hierarchy] WITH CHECK ADD CONSTRAINT [FK_Hierarchy_Function] FOREIGN KEY([ParentFunction_ID])
REFERENCES [dbo].[Function] ([Function_ID])
GO
ALTER TABLE [dbo].[Hierarchy] CHECK CONSTRAINT [FK_Hierarchy_Function]
GO
ALTER TABLE [dbo].[Hierarchy] WITH CHECK ADD CONSTRAINT [FK_Hierarchy_Function1] FOREIGN KEY([ChildFunction_ID])
REFERENCES [dbo].[Function] ([Function_ID])
GO
ALTER TABLE [dbo].[Hierarchy] CHECK CONSTRAINT [FK_Hierarchy_Function1]
GO