Create tables for Dynamic Product - sql

I want user can create Product category And if it Have SubCategory.define SubCategory.then define column in tables(Brand,Group And Field) Of that Category(or SubCategory).Finally user can add Product Based that Brand,Group And Field column that define before.
I Want to create Dynamic Product Database and this my first time for create dynamic tables.I just worry about
1-Correct Creation
2-performance issue(no doubt about types).
I add my diagram Tables and script of tables
CREATE TABLE [dbo].[CategoryBrand](
[ProductCategoryId] [tinyint] NOT NULL,
[ProductBrandId] [tinyint] NOT NULL,
CONSTRAINT [PK_CategoryBrand] PRIMARY KEY CLUSTERED
(
[ProductCategoryId] ASC,
[ProductBrandId] 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
/****** Object: Table [dbo].[Group] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Group](
[Id] [smallint] IDENTITY(1,1) NOT NULL,
[ProductCategoryId] [tinyint] NOT NULL,
[GroupName] [nvarchar](250) NOT NULL,
CONSTRAINT [PK_aaa] 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
/****** Object: Table [dbo].[GroupInfo] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[GroupInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[GroupId] [smallint] NOT NULL,
[SubGroupName] [nvarchar](500) NOT NULL,
CONSTRAINT [PK_GroupInfo] 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
/****** Object: Table [dbo].[Product] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Product](
[Id] [int] IDENTITY(1,1) NOT NULL,
[CategoryId] [tinyint] NOT NULL,
[Describtion] [nvarchar](max) NULL,
[ProductBrandId] [tinyint] NOT NULL,
CONSTRAINT [PK_Product] 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] TEXTIMAGE_ON [PRIMARY]
GO
/****** Object: Table [dbo].[ProductBrand] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductBrand](
[Id] [tinyint] IDENTITY(1,1) NOT NULL,
[BrandName] [nvarchar](50) NOT NULL,
[ImageAddress] [nvarchar](500) NULL,
CONSTRAINT [PK_ProductBrand] 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
/****** Object: Table [dbo].[ProductCategory] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductCategory](
[Id] [tinyint] IDENTITY(1,1) NOT NULL,
[Category] [nvarchar](250) NOT NULL,
[ParentId] [tinyint] NULL,
CONSTRAINT [PK_ProductCategory] 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
/****** Object: Table [dbo].[ProductField] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductField](
[Id] [smallint] IDENTITY(1,1) NOT NULL,
[ProductCategoryId] [tinyint] NOT NULL,
[FieldName] [nvarchar](100) NOT NULL,
[Describtion] [nvarchar](1000) NULL,
CONSTRAINT [PK_ProductField] 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
/****** Object: Table [dbo].[ProductFieldInfo] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductFieldInfo](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ProductId] [int] NOT NULL,
[ProductFieldId] [smallint] NOT NULL,
[FieldInfo] [nvarchar](1000) NOT NULL,
CONSTRAINT [PK_ProductFieldInfo] 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
/****** Object: Table [dbo].[ProductGroup] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductGroup](
[ProductId] [int] NOT NULL,
[GroupIfoId] [int] NOT NULL,
CONSTRAINT [PK_ProductGroup] PRIMARY KEY CLUSTERED
(
[ProductId] ASC,
[GroupIfoId] 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
/****** Object: Table [dbo].[ProductImage] Script Date: 6/19/2016 11:15:18 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ProductImage](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ProductId] [int] NOT NULL,
[FileName] [nvarchar](500) NULL,
[ImageAddress] [nvarchar](500) NOT NULL,
CONSTRAINT [PK_ProductImage] 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].[CategoryBrand] WITH CHECK ADD CONSTRAINT [FK_CategoryBrand_ProductBrand] FOREIGN KEY([ProductBrandId])
REFERENCES [dbo].[ProductBrand] ([Id])
GO
ALTER TABLE [dbo].[CategoryBrand] CHECK CONSTRAINT [FK_CategoryBrand_ProductBrand]
GO
ALTER TABLE [dbo].[CategoryBrand] WITH CHECK ADD CONSTRAINT [FK_CategoryBrand_ProductCategory] FOREIGN KEY([ProductCategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[CategoryBrand] CHECK CONSTRAINT [FK_CategoryBrand_ProductCategory]
GO
ALTER TABLE [dbo].[Group] WITH CHECK ADD CONSTRAINT [FK_aaa_ProductCategory] FOREIGN KEY([ProductCategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[Group] CHECK CONSTRAINT [FK_aaa_ProductCategory]
GO
ALTER TABLE [dbo].[GroupInfo] WITH CHECK ADD CONSTRAINT [FK_GroupInfo_aaa] FOREIGN KEY([GroupId])
REFERENCES [dbo].[Group] ([Id])
GO
ALTER TABLE [dbo].[GroupInfo] CHECK CONSTRAINT [FK_GroupInfo_aaa]
GO
ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_Product_ProductBrand] FOREIGN KEY([ProductBrandId])
REFERENCES [dbo].[ProductBrand] ([Id])
GO
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductBrand]
GO
ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_Product_ProductCategory] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_Product_ProductCategory]
GO
ALTER TABLE [dbo].[ProductCategory] WITH CHECK ADD CONSTRAINT [FK_ProductCategory_ProductCategory] FOREIGN KEY([ParentId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[ProductCategory] CHECK CONSTRAINT [FK_ProductCategory_ProductCategory]
GO
ALTER TABLE [dbo].[ProductField] WITH CHECK ADD CONSTRAINT [FK_ProductField_ProductCategory] FOREIGN KEY([ProductCategoryId])
REFERENCES [dbo].[ProductCategory] ([Id])
GO
ALTER TABLE [dbo].[ProductField] CHECK CONSTRAINT [FK_ProductField_ProductCategory]
GO
ALTER TABLE [dbo].[ProductFieldInfo] WITH CHECK ADD CONSTRAINT [FK_ProductFieldInfo_Product] FOREIGN KEY([ProductId])
REFERENCES [dbo].[Product] ([Id])
GO
ALTER TABLE [dbo].[ProductFieldInfo] CHECK CONSTRAINT [FK_ProductFieldInfo_Product]
GO
ALTER TABLE [dbo].[ProductFieldInfo] WITH CHECK ADD CONSTRAINT [FK_ProductFieldInfo_ProductField] FOREIGN KEY([ProductFieldId])
REFERENCES [dbo].[ProductField] ([Id])
GO
ALTER TABLE [dbo].[ProductFieldInfo] CHECK CONSTRAINT [FK_ProductFieldInfo_ProductField]
GO
ALTER TABLE [dbo].[ProductGroup] WITH CHECK ADD CONSTRAINT [FK_ProductGroup_GroupInfo] FOREIGN KEY([GroupIfoId])
REFERENCES [dbo].[GroupInfo] ([Id])
GO
ALTER TABLE [dbo].[ProductGroup] CHECK CONSTRAINT [FK_ProductGroup_GroupInfo]
GO
ALTER TABLE [dbo].[ProductGroup] WITH CHECK ADD CONSTRAINT [FK_ProductGroup_Product] FOREIGN KEY([ProductId])
REFERENCES [dbo].[Product] ([Id])
GO
ALTER TABLE [dbo].[ProductGroup] CHECK CONSTRAINT [FK_ProductGroup_Product]
GO
ALTER TABLE [dbo].[ProductImage] WITH CHECK ADD CONSTRAINT [FK_ProductImage_Product] FOREIGN KEY([ProductId])
REFERENCES [dbo].[Product] ([Id])
GO
ALTER TABLE [dbo].[ProductImage] CHECK CONSTRAINT [FK_ProductImage_Product]
GO

If it is your first time then make things simple.
Do not use dynamic SQL to create objects.
Before you do your design, review the well known AdventureWorks database. It has similar structure, where you can get some ideas:
http://msftdbprodsamples.codeplex.com/releases
If AdventureWorks will not satisfy you, then ask questions on how to modify it for your business needs.

I Find My Answer:
this is Database Table that I Want Design with Some Changes:
designing database to hold different metadata information

Related

Trigger to update table after insert to insert or update into another table

I am having a little trouble with my after insert trigger it does not update/insert into the table and I am not sure why.
I have the tables employee, position, certification, employeecertification, positioncertification.
What I need to do is after a Position is assigned a Certification then all employees that are defined in that position (Employee:PositionId = Ins.PositionId] need to get the certification added (if it does not already exist in their record) , I might need to update them where they do exist (but for the moment do not believe that will be a requirement).
I have been getting a couple different results (neither is correct)
1: EmployeeId can not insert null into EmployeeId
2: On some other test data - nothing is inserted.
I have the following trigger with the sql for creation of tables that follows:
The Trigger
CREATE TRIGGER [dbo].[trig_InsNew_PositionCertification]
ON [dbo].[PositionCertification]
AFTER INSERT
AS
Insert into EmployeeCertification
(CertificationId, EmployeeId)
Select Ins.CertificationId, Emp.EmployeeId
From inserted Ins
Left Join dbo.Employee Emp On Emp.PositionId = Ins.PositionId
Left Join dbo.Certification Trw On Trw.CertificationId = Ins.CertificationId
WHERE NOT EXISTS
(SELECT EmployeeId, CertificationId
FROM
EmployeeCertification
WHERE EmployeeId = Emp.EmployeeId AND CertificationId = Ins.CertificationId);
GO
ALTER TABLE [dbo].[PositionCertification] ENABLE TRIGGER [trig_InsNew_PositionCertification]
GO
CREATE TABLES:
CREATE TABLE [dbo].[Position](
[PositionId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_Position] PRIMARY KEY CLUSTERED
(
[PositionId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Employee](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[EmployeeName] [nvarchar](512) NOT NULL,
[PositionId] [int] NOT NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeId] 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].[Employee] WITH CHECK ADD CONSTRAINT [FK_Employee_Position] FOREIGN KEY([PositionId])
REFERENCES [dbo].[Position] ([PositionId])
GO
ALTER TABLE [dbo].[Position] CHECK CONSTRAINT [FK_Employee_Position]
GO
CREATE TABLE [dbo].[Certification](
[CertificationId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](512) NOT NULL,
CONSTRAINT [PK_Certification] PRIMARY KEY CLUSTERED
(
[CertificationId] 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].[EmployeeCertification](
[EmployeeCertificationId] [int] IDENTITY(1,1) NOT NULL,
[EmployeeId] [int] NOT NULL,
[CertificationId] [int] NOT NULL,
CONSTRAINT [PK_EmployeeCertification] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC,
[CertificationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[EmployeeCertification] WITH CHECK ADD CONSTRAINT [FK_EmpCertification_Certification] FOREIGN KEY([CertificationId])
REFERENCES [dbo].[Certification] ([CertificationId])
GO
ALTER TABLE [dbo].[EmployeeCertification] CHECK CONSTRAINT [FK_EmpCertification_Certification]
GO
ALTER TABLE [dbo].[EmployeeCertification] WITH CHECK ADD CONSTRAINT [FK_EmpCertification_Employee] FOREIGN KEY([EmployeeId])
REFERENCES [dbo].[Employee] ([EmployeeId])
GO
ALTER TABLE [dbo].[EmployeeCertification] CHECK CONSTRAINT [FK_EmpCertification_Employee]
GO
CREATE TABLE [dbo].[PositionCertification](
[PositionCertificationId] [int] IDENTITY(1,1) NOT NULL,
[PositionId] [int] NOT NULL,
[CertificationId] [int] NOT NULL,
CONSTRAINT [PK_PositionCertification] PRIMARY KEY CLUSTERED
(
[PositionId] ASC,
[CertificationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Foreign Keys for 4 tables in a GrandParent, Parent, Child, GrandChild so change the Parent Field cascades to GrandChild

I need to be able to change the Chain_ID in the parent table and have it cascade down to the assemblies table through use of foreign keys.
Currently there are foreign keys between the Stores and Machines which does work as when I change the Chain_ID in the Store table it does change the Chain_ID in the Machines table.
However the foreign key on the Machine and Assemblies tables does not update the Assemblies table Chain_ID.
Any help would be greatly appreciated
Database layout
USE [Test_DB]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Chains]
(
**[Chain_ID]** [INT] IDENTITY(1001,1) NOT NULL,
[Chain_Name] [NVARCHAR](50) NOT NULL,
CONSTRAINT [PK__ChainID]
PRIMARY KEY CLUSTERED ([Chain_ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Stores]
(
**[Chain_ID]** [INT] NOT NULL,
**[Store_ID]** [INT] NOT NULL,
[Store_Name] [NVARCHAR](50) NULL,
CONSTRAINT [PK__ChainID_StoreID]
PRIMARY KEY CLUSTERED ([Chain_ID] ASC, [Store_ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
CREATE TABLE [dbo].[Machines]
(
[Machine_ID] [INT] IDENTITY(10001,1) NOT NULL,
**[Chain_ID]** [INT] NOT NULL,
**[Store_ID]** [INT] NOT NULL,
[Status] [NVARCHAR](10) NULL,
[Comments] [NVARCHAR](200) NULL,
CONSTRAINT [PK__MachineID]
PRIMARY KEY CLUSTERED ([Machine_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].[Machines] WITH CHECK
ADD CONSTRAINT [FK__Machines_Stores]
FOREIGN KEY ([Chain_ID], [Store_ID])
REFERENCES [dbo].[Stores] ([Chain_ID], [Store_ID])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[Machines] CHECK CONSTRAINT [FK__Machines_Stores]
GO
CREATE TABLE [dbo].[Assemblies]
(
[Serial_Number] [NVARCHAR](11) NOT NULL,
[Machine_ID] [INT] NOT NULL,
**[Chain_ID]** [INT] NOT NULL,
**[Store_ID]** [INT] NOT NULL,
[Equipment_Type] [NVARCHAR](42) NULL,
[Status] [NVARCHAR](10) NULL,
CONSTRAINT [PK__Serial_Number]
PRIMARY KEY CLUSTERED ([Serial_Number] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = ON, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Assemblies] WITH CHECK
ADD CONSTRAINT [FK__Assemblies_Machines]
FOREIGN KEY([Machine_ID])
REFERENCES [dbo].[Test_DB] ([Machine_ID])
ON UPDATE CASCADE
GO
ALTER TABLE [dbo].[Assemblies] CHECK CONSTRAINT [FK__Assemblies_Machines]
GO

Cascading delete rows from multiple tables in SQL

I've got two tables with the following structure:
Person
Id
Name
Class
Id
PersonId
Sequence
and some data:
Person
1 name1
2 name2
3 name3
Class
1 1 3
2 1 1
3 1 2
4 2 1
Class table can contain multiple rows related to one row from Person. PersonId from Class table is foreign key to Id in Person table. I'd like to delete data related to Person with Id 1, so remove the 3 rows from Class, and 1 row from Person using one query.
How can I do that in SQL?
Try This:
CREATE TABLE [dbo].[Class](
[Id] [int] IDENTITY(1,1) NOT NULL,
[PersonId] [int] NULL,
[Sequence] [int] NULL,
CONSTRAINT [PK_Class] 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
/****** Object: Table [dbo].[Person] Script Date: 26-05-2014 07:54:26 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Person](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Person] [nchar](10) NULL,
CONSTRAINT [PK_Person] 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].[Class] WITH CHECK ADD CONSTRAINT [FK_Class_Person] FOREIGN KEY([PersonId])
REFERENCES [dbo].[Person] ([Id])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Class] CHECK CONSTRAINT [FK_Class_Person]
GO

How to get set-based solution for a difficult join

I've got a Table with a list of Products.
I've got a Table with a list of Merchants.
I've got a Table with a list of Warehouses.
I've got a WarehouseMerchant Table so a a warehouse can have many merchants assigned.
I've got a WarehouseMerchantProduct Table so a merchant can have its products listed in a warehouse
I've got a Merchant Link Table which can link 2 merchants
MerchantLinkID int
MasterMerchantID int
LinkedMerchantID int
PreferenceOrder int
What i need to do is pass in a product ID and get a unique list of merchants products who can sell it.
4 Rules
If the merchant has a linked merchant who also sells the product, then don't show the linked merchants product
If the merchant has a linked merchant who also sells the product, but the master merchants stock level is 0, then only show the linked merchants product
In the event that a merchant has stock in multiple warehouses, then there is a preference order in the warehouseMerchant Table to select which one to use
There should only be one product per merchant after this has all ran
I've been racking my brains trying to figure out a solution. I was going down the route of cursors, but it was getting a bit unwieldy. Then i was given the 4 rules as a requirement which sent me back to the drawing board.
If anyone can think of a quick and easy(ish) set-based solution for this then I'd love to hear it.
Here is the script to create the tables and relationships
CREATE TABLE [dbo].[MW_Merchant](
[MerchantID] [int] IDENTITY(1,1) NOT NULL,
[MerchantName] [nvarchar](150) NOT NULL,
[MerchantCode] [char](10) NOT NULL,
[Active] [bit] NOT NULL,
CONSTRAINT [PK_Merchant] PRIMARY KEY CLUSTERED
(
[MerchantID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
CONSTRAINT [ucMerchantCode] UNIQUE NONCLUSTERED
(
[MerchantCode] 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
/****** Object: Table [dbo].[MW_Warehouse] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MW_Warehouse](
[WarehouseID] [int] IDENTITY(1,1) NOT NULL,
[WarehouseName] [nvarchar](150) NOT NULL,
[WarehouseCode] [varchar](10) NOT NULL,
[Active] [bit] NOT NULL,
CONSTRAINT [PK_Warehouse] PRIMARY KEY CLUSTERED
(
[WarehouseID] 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
/****** Object: Table [dbo].[MW_WarehouseMerchantProduct] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[MW_WarehouseMerchantProduct](
[WarehouseMerchantProductID] [int] IDENTITY(1,1) NOT NULL,
[WarehouseID] [int] NOT NULL,
[MerchantID] [int] NOT NULL,
[ProductCode] [varchar](30) NOT NULL,
[StockLevel] [int] NOT NULL,
[Active] [bit] NOT NULL,
[PriorityOrder] [int] NOT NULL,
CONSTRAINT [PK_MW_WarehouseProduct] PRIMARY KEY CLUSTERED
(
[WarehouseMerchantProductID] 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
/****** Object: Table [dbo].[MW_WarehouseMerchant] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MW_WarehouseMerchant](
[WarehouseMerchantID] [int] IDENTITY(1,1) NOT NULL,
[WarehouseID] [int] NOT NULL,
[MerchantID] [int] NOT NULL,
[Active] [bit] NOT NULL,
[PreferenceOrder] [int] NOT NULL,
CONSTRAINT [PK_MW_WarehouseMerchant] PRIMARY KEY CLUSTERED
(
[WarehouseMerchantID] 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
/****** Object: Table [dbo].[MW_MerchantLink] Script Date: 04/30/2013 09:17:39 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MW_MerchantLink](
[MerchantLinkID] [int] IDENTITY(1,1) NOT NULL,
[MasterMerchantID] [int] NOT NULL,
[LinkedMerchantID] [int] NOT NULL,
[PreferenceOrder] [int] NOT NULL,
CONSTRAINT [PK_MW_MerchantLink] PRIMARY KEY CLUSTERED
(
[MerchantLinkID] 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
/****** Object: Default [DF_MW_WarehouseMerchant_PreferenceOrder] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchant] ADD CONSTRAINT [DF_MW_WarehouseMerchant_PreferenceOrder] DEFAULT ((10)) FOR [PreferenceOrder]
GO
/****** Object: Default [DF_MW_WarehouseMerchantProduct_PriorityOrder] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] ADD CONSTRAINT [DF_MW_WarehouseMerchantProduct_PriorityOrder] DEFAULT ((10)) FOR [PriorityOrder]
GO
/****** Object: ForeignKey [FK_MW_MerchantLink_MW_Merchant] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_MerchantLink] WITH CHECK ADD CONSTRAINT [FK_MW_MerchantLink_MW_Merchant] FOREIGN KEY([MasterMerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_MerchantLink] CHECK CONSTRAINT [FK_MW_MerchantLink_MW_Merchant]
GO
/****** Object: ForeignKey [FK_MW_MerchantLink_MW_Merchant1] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_MerchantLink] WITH CHECK ADD CONSTRAINT [FK_MW_MerchantLink_MW_Merchant1] FOREIGN KEY([LinkedMerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_MerchantLink] CHECK CONSTRAINT [FK_MW_MerchantLink_MW_Merchant1]
GO
/****** Object: ForeignKey [FK_MW_WarehouseMerchant_MW_Merchant] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchant] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseMerchant_MW_Merchant] FOREIGN KEY([MerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchant] CHECK CONSTRAINT [FK_MW_WarehouseMerchant_MW_Merchant]
GO
/****** Object: ForeignKey [FK_MW_WarehouseMerchant_MW_Warehouse] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchant] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseMerchant_MW_Warehouse] FOREIGN KEY([WarehouseID])
REFERENCES [dbo].[MW_Warehouse] ([WarehouseID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchant] CHECK CONSTRAINT [FK_MW_WarehouseMerchant_MW_Warehouse]
GO
/****** Object: ForeignKey [FK_MW_WarehouseMerchantProduct_MW_Merchant] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseMerchantProduct_MW_Merchant] FOREIGN KEY([MerchantID])
REFERENCES [dbo].[MW_Merchant] ([MerchantID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] CHECK CONSTRAINT [FK_MW_WarehouseMerchantProduct_MW_Merchant]
GO
/****** Object: ForeignKey [FK_MW_WarehouseProduct_MW_Warehouse] Script Date: 04/30/2013 09:17:39 ******/
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] WITH CHECK ADD CONSTRAINT [FK_MW_WarehouseProduct_MW_Warehouse] FOREIGN KEY([WarehouseID])
REFERENCES [dbo].[MW_Warehouse] ([WarehouseID])
GO
ALTER TABLE [dbo].[MW_WarehouseMerchantProduct] CHECK CONSTRAINT [FK_MW_WarehouseProduct_MW_Warehouse]
GO
And some test data
/****** Object: Table [dbo].[MW_Merchant] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_Merchant] ON
INSERT [dbo].[MW_Merchant] ([MerchantID], [MerchantName], [MerchantCode], [Active]) VALUES (24, N'Merchant 1', N'MERCH1 ', 1)
INSERT [dbo].[MW_Merchant] ([MerchantID], [MerchantName], [MerchantCode], [Active]) VALUES (27, N'Merchant 2', N'MERCH2 ', 1)
INSERT [dbo].[MW_Merchant] ([MerchantID], [MerchantName], [MerchantCode], [Active]) VALUES (28, N'Merchant 3', N'MERCH3 ', 1)
SET IDENTITY_INSERT [dbo].[MW_Merchant] OFF
/****** Object: Table [dbo].[MW_Warehouse] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_Warehouse] ON
INSERT [dbo].[MW_Warehouse] ([WarehouseID], [WarehouseName], [WarehouseCode], [Active]) VALUES (12, N'Warehouse 1', N'WARE1', 1)
INSERT [dbo].[MW_Warehouse] ([WarehouseID], [WarehouseName], [WarehouseCode], [Active]) VALUES (13, N'Warehouse 2', N'WARE2', 1)
INSERT [dbo].[MW_Warehouse] ([WarehouseID], [WarehouseName], [WarehouseCode], [Active]) VALUES (14, N'Warehouse 3', N'WARE3', 1)
SET IDENTITY_INSERT [dbo].[MW_Warehouse] OFF
/****** Object: Table [dbo].[MW_WarehouseMerchantProduct] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_WarehouseMerchantProduct] ON
INSERT [dbo].[MW_WarehouseMerchantProduct] ([WarehouseMerchantProductID], [WarehouseID], [MerchantID], [ProductCode], [StockLevel], [Active], [PriorityOrder]) VALUES (93, 13, 24, N'TESTPRODUCT', 20, 1, 10)
INSERT [dbo].[MW_WarehouseMerchantProduct] ([WarehouseMerchantProductID], [WarehouseID], [MerchantID], [ProductCode], [StockLevel], [Active], [PriorityOrder]) VALUES (96, 14, 24, N'TESTPRODUCT', 20, 1, 10)
INSERT [dbo].[MW_WarehouseMerchantProduct] ([WarehouseMerchantProductID], [WarehouseID], [MerchantID], [ProductCode], [StockLevel], [Active], [PriorityOrder]) VALUES (97, 14, 27, N'TESTPRODUCT', 10, 1, 10)
SET IDENTITY_INSERT [dbo].[MW_WarehouseMerchantProduct] OFF
/****** Object: Table [dbo].[MW_MerchantLink] Script Date: 04/30/2013 09:41:50 ******/
SET IDENTITY_INSERT [dbo].[MW_MerchantLink] ON
INSERT [dbo].[MW_MerchantLink] ([MerchantLinkID], [MasterMerchantID], [LinkedMerchantID], [PreferenceOrder]) VALUES (22, 24, 27, 1)
INSERT [dbo].[MW_MerchantLink] ([MerchantLinkID], [MasterMerchantID], [LinkedMerchantID], [PreferenceOrder]) VALUES (23, 24, 28, 2)
SET IDENTITY_INSERT [dbo].[MW_MerchantLink] OFF
In the example data, my returned row should be the WarehouseMerchantProductID 93
93,96 and 97 all have stock, however
93 and 96 belong to the same merchant and should be selected based on PreferenceOrder in the WarehouseMerchant Table
Merchant 27 is linked to 24 so shouldnt appear (unless 24 goes out of stock)
Note, the following query is written for Oracle and assumes that a LinkedMerchant only has 1 MasterMerchant. You can play around with the code here. Also note that I have included more test data than you provided in order to test some additional cases.
SELECT MERCHANTID, WAREHOUSEID, PRODUCTCODE
FROM (
SELECT 0
, WMP.MERCHANTID
, WMP.WAREHOUSEID
, WMP.PRODUCTCODE
, RANK() OVER (PARTITION BY ML.MASTERMERCHANTID, WMP.PRODUCTCODE ORDER BY ML.PREFERENCEORDER ASC NULLS LAST) MERCH_RANK
, RANK() OVER (PARTITION BY WMP.MERCHANTID, WMP.PRODUCTCODE ORDER BY WM.PREFERENCEORDER ASC NULLS LAST) WARE_RANK
FROM MW_WAREHOUSEMERCHANTPRODUCT WMP
LEFT OUTER JOIN MW_WAREHOUSEMERCHANT WM ON 0=0
AND WMP.MERCHANTID = WM.MERCHANTID
AND WMP.WAREHOUSEID = WM.WAREHOUSEID
LEFT OUTER JOIN MW_MERCHANTLINK ML ON 0=0
AND WMP.MERCHANTID = ML.LINKEDMERCHANTID
LEFT OUTER JOIN MW_WAREHOUSEMERCHANTPRODUCT MASTER ON 0=0
AND ML.MASTERMERCHANTID = MASTER.MERCHANTID
AND WMP.PRODUCTCODE = MASTER.PRODUCTCODE
WHERE 0=0
AND WMP.STOCKLEVEL > 0
AND NVL(MASTER.STOCKLEVEL, 0) <= 0
)
WHERE 0=0
AND MERCH_RANK = 1
AND WARE_RANK = 1
;

How should I migrate this data into these Sql Server tables?

I wish to migrate some data from a single table into these new THREE tables.
Here's my destination schema:
Notice that I need to insert into the first Location table .. grab the SCOPE_IDENTITY() .. then insert the rows into the Boundary and Country tables.
The SCOPE_IDENTITY() is killing me :( meaning, I can only see a way to do this via CURSORS. Is there a better alternative?
UPDATE
Here's the scripts for the DB Schema....
Location
CREATE TABLE [dbo].[Locations](
[LocationId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](100) NOT NULL,
[OriginalLocationId] [int] NOT NULL,
CONSTRAINT [PK_Locations] PRIMARY KEY CLUSTERED
(
[LocationId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
)
Country
CREATE TABLE [dbo].[Locations_Country](
[IsoCode] [nchar](2) NOT NULL,
[LocationId] [int] NOT NULL,
CONSTRAINT [PK_Locations_Country] PRIMARY KEY CLUSTERED
(
[LocationId] 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].[Locations_Country] WITH CHECK ADD CONSTRAINT [FK_Country_inherits_Location] FOREIGN KEY([LocationId])
REFERENCES [dbo].[Locations] ([LocationId])
GO
ALTER TABLE [dbo].[Locations_Country] CHECK CONSTRAINT [FK_Country_inherits_Location]
GO
Boundary
CREATE TABLE [dbo].[Boundaries](
[LocationId] [int] NOT NULL,
[CentrePoint] [varbinary](max) NOT NULL,
[OriginalBoundary] [varbinary](max) NULL,
[LargeReducedBoundary] [varbinary](max) NULL,
[MediumReducedBoundary] [varbinary](max) NULL,
[SmallReducedBoundary] [varbinary](max) NULL,
CONSTRAINT [PK_Boundaries] PRIMARY KEY CLUSTERED
(
[LocationId] 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].[Boundaries] WITH CHECK ADD CONSTRAINT [FK_LocationBoundary] FOREIGN KEY([LocationId])
REFERENCES [dbo].[Locations] ([LocationId])
GO
ALTER TABLE [dbo].[Boundaries] CHECK CONSTRAINT [FK_LocationBoundary]
GO
I don't see a need for SCOPE_IDENTITY or cursors if you approach the data in order of the parent/child relationship:
INSERT INTO LOCATION
SELECT t.name,
t.originallocationid
FROM ORIGINAL_TABLE t
GROUP BY t.name, t.originallocationid
INSERT INTO COUNTRY
SELECT DISTINCT
t.isocode,
l.locationid
FROM ORIGINAL_TABLE t
JOIN LOCATION l ON l.name = t.name
AND l.originallocationid = t.originalocationid
INSERT INTO BOUNDARY
SELECT DISTINCT
l.locationid,
t.centrepoint,
t.originalboundary,
t.largereducedboundary,
t.mediumreducedboundary,
t.smallreducedboundary
FROM ORIGINAL_TABLE t
JOIN LOCATION l ON l.name = t.name
AND l.originallocationid = t.originalocationid
After loading your Location table you could create a query that joins Location with your source single table. The join criteria would be the natural key (is that the Name column?) and it would return the new LocationId along with the Boundary data. The results would inserted into the new Boundary table.