Constraint with multiple tables. UDF? - sql-server

I have two tables: table A and table B. These two tables are linked with a primary key in A and a foreign key in B.
Table A:
CREATE TABLE [BIO].[table_A](
[table_A_id] [int] IDENTITY(1,1) NOT NULL,
[type_id] [nvarchar](2) NOT NULL
CONSTRAINT [PK_table_A] PRIMARY KEY CLUSTERED
(
[table_A_id] ASC
))
Table B:
CREATE TABLE [BIO].[table_B](
[table_B_id] [int] IDENTITY(1,1) NOT NULL,
[table_A_id] [int] NOT NULL,
[analysis_id] [tinyint] NOT NULL
CONSTRAINT [PK_table_B] PRIMARY KEY CLUSTERED
(
[table_B_id] ASC
))
ALTER TABLE [BIO].[table_B] WITH CHECK
ADD CONSTRAINT [FK_table_B_table_A] FOREIGN KEY([table_A_id])
REFERENCES [BIO].[table_A] ([table_A_id])
GO
ALTER TABLE [BIO].[table_B] CHECK CONSTRAINT [FK_table_B_table_A]
GO
Table B must contain only specific values according to the values in table A.
For example, if I have BL in table A, I can only have 1 or 3 in table B; if I have ST in table A, I can only have 2 or 4 in table B.
I have setup a bridge table which defines these combinations: BL→1 or 3, ST→2 or 4.
Bridge table:
CREATE TABLE [QRY].[bridge_table](
[type_id] [nvarchar](2) NOT NULL,
[analysis_id] [tinyint] NOT NULL,
CONSTRAINT [PK_bridge_table] PRIMARY KEY CLUSTERED
(
[type_id] ASC,
[analysis_id] ASC
))
I am currently using one constraint per table to be sure that any insert or update is correct according to the combinations defined in the bridge table. These two constraints are based on UDFs.
Constraint on table B:
ALTER TABLE [BIO].[Table_B] WITH CHECK
ADD CONSTRAINT [CK_chkAnalysisType]
CHECK (([QRY].[TypeAnalysisMatch_table_B]([table_A_id])>(0)))
GO
UDF:
CREATE FUNCTION [QRY].[TypeAnalysisMatch_table_B] (#table_A_id int)
RETURNS int
AS
BEGIN
RETURN
(
SELECT
Count(BIO.table_A.table_A_id) AS cnt_rec
FROM
QRY.bridge_table
INNER JOIN BIO.table_A ON QRY.bridge_table.type_id = BIO.table_A.type_id
INNER JOIN BIO.table_B ON
QRY.bridge_table.analysis_id = BIO.table_B.analysis_id
AND BIO.table_A.table_A_id = BIO.table_B.table_A_id
WHERE
BIO.table_A.table_A_id = #table_A_id
)
END
It works well for the INSERT but not consistently for the UPDATE. Moreover, as I read that UDFs in constraints should be avoided, I am looking for a better solution.
What would be an efficient alternative to these constraints?

You are right, having UDF in CHECK constraints can be tricky and some UPDATE statements may bypass the check:
http://sqlblog.com/blogs/tibor_karaszi/archive/2009/12/17/be-careful-with-constraints-calling-udfs.aspx
MSSQL: Update statement avoiding the CHECK constraint
As you can see in that SO question the answer recommended to use trigger for the check. Writing a correct efficient trigger is also not an easy task.
I assume that your bridge_table contains this data:
type_id analysis_id
BL 1
BL 3
ST 2
ST 4
I would set up these constraints using only foreign keys, without UDF. It would require some (minimal) duplication of the data, though. I assume that real table_A and table_B have more columns than this example.
1. In table_A include type_id in the primary key:
CREATE TABLE [table_A](
[table_A_id] [int] IDENTITY(1,1) NOT NULL,
[type_id] [nvarchar](2) NOT NULL,
CONSTRAINT [PK_table_A] PRIMARY KEY CLUSTERED
(
[table_A_id] ASC,
[type_id] ASC
))
2. Add a column type_id to the table_B. Yes, the same column as you already have in table_A. This is that duplication of data that I mentioned above:
CREATE TABLE [table_B](
[table_B_id] [int] IDENTITY(1,1) NOT NULL,
[table_A_id] [int] NOT NULL,
[type_id] [nvarchar](2) NOT NULL,
[analysis_id] [tinyint] NOT NULL
CONSTRAINT [PK_table_B] PRIMARY KEY CLUSTERED
(
[table_B_id] ASC
))
3. Make foreign key that links table_B with table_A on two columns (table_A_id, type_id):
ALTER TABLE [table_B] WITH CHECK
ADD CONSTRAINT [FK_table_B_table_A] FOREIGN KEY([table_A_id], [type_id])
REFERENCES [table_A] ([table_A_id], [type_id])
This constraint guarantees that type_id values that are duplicated in table_B will be consistent with original values from table_A.
4. Make foreign key that links table_B with bridge_table again on two columns (type_id, analysis_id):
ALTER TABLE [table_B] WITH CHECK
ADD CONSTRAINT [FK_table_B_bridge_table] FOREIGN KEY([type_id], [analysis_id])
REFERENCES [bridge_table] ([type_id], [analysis_id])
5. Now you can test that everything works as intended.
Add few rows to table_A:
INSERT INTO [table_A] ([type_id])
VALUES ('BL'), ('BL'), ('ST'), ('ZZ');
table_A_id type_id
1 BL
2 BL
3 ST
4 ZZ
Try to insert valid data into table_B:
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (1,'BL',1)
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (1,'BL',3)
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (2,'BL',3)
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (3,'ST',2)
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (3,'ST',2)
table_B_id table_A_id type_id analysis_id
1 1 BL 1
2 1 BL 3
3 2 BL 3
4 3 ST 2
5 3 ST 2
Try to insert invalid data:
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (3,'ST',1)
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_table_B_bridge_table".
The conflict occurred in database "tempdb", table "dbo.bridge_table".
The statement has been terminated.
Which means, that ST can't have analysis_id=1
INSERT INTO [dbo].[table_B] ([table_A_id],[type_id],[analysis_id])
VALUES (3,'BL',1)
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_table_B_table_A".
The conflict occurred in database "tempdb", table "dbo.table_A".
The statement has been terminated.
Which means, that the row in table_A with table_A_id=3 doesn't have BL in type_id.
Foreign keys would keep checking data consistency for all UPDATE statements as well:
UPDATE [dbo].[table_B]
SET [type_id] = 'ST'
WHERE [table_B_id] = 1
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_table_B_table_A".
The conflict occurred in database "tempdb", table "dbo.table_A".
The statement has been terminated.
UPDATE [dbo].[table_B]
SET [analysis_id] = 2
WHERE [table_B_id] = 1
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_table_B_bridge_table".
The conflict occurred in database "tempdb", table "dbo.bridge_table".
The statement has been terminated.
But this one works:
UPDATE [dbo].[table_B]
SET [analysis_id] = 3
WHERE [table_B_id] = 1
(1 row(s) affected)

Related

Why does SCOPE_IDENTITY() return NULL after insert on one table and not on the other?

Why does SCOPE_IDENTITY() return NULL after inserting a row in the ComponentAssociation table (as ##IDENTITY returns the right Id)
while SCOPE_IDENTITY() returns the right Id after inserting a row in the CustomerProjectAssociation table ?
The two association tables are created the same way.
Here is an extract of the table creation script:
-- Creating table 'CustomerProjectAssociation'
CREATE TABLE [dbo].[CustomerProjectAssociation]
(
[Id] int IDENTITY(1,1) NOT NULL,
[CustomerId] int NOT NULL,
[ProjectId] int NOT NULL,
[CreationDate] datetime NOT NULL CONSTRAINT DF_CustomerProjectAssociation_CreationDate DEFAULT (SYSUTCDATETIME()),
[LastModificationDate] datetime NOT NULL CONSTRAINT DF_CustomerProjectAssociation_ModificationDate DEFAULT (SYSUTCDATETIME())
);
GO
-- Creating table 'ComponentAssociation'
CREATE TABLE [dbo].[ComponentAssociation]
(
[Id] int IDENTITY(1,1) NOT NULL,
[EcuId] int NOT NULL,
[CreationDate] datetime NOT NULL CONSTRAINT DF_ComponentAssociation_CreationDate DEFAULT (SYSUTCDATETIME()),
[LastModificationDate] datetime NOT NULL CONSTRAINT DF_ComponentAssociation_ModificationDate DEFAULT (SYSUTCDATETIME()),
[ComponentId] int NOT NULL
);
GO
-- Creating primary key on [Id] in table 'CustomerProjectAssociation'
ALTER TABLE [dbo].[CustomerProjectAssociation]
ADD CONSTRAINT [PK_CustomerProjectAssociation]
PRIMARY KEY CLUSTERED ([Id] ASC);
GO
-- Creating primary key on [Id] in table 'ComponentAssociation'
ALTER TABLE [dbo].[ComponentAssociation]
ADD CONSTRAINT [PK_ComponentAssociation]
PRIMARY KEY CLUSTERED ([Id] ASC);
GO
And here are two queries executed on the database from SQL Server Management Studio:
INSERT [dbo].[CustomerProjectAssociation]([CustomerId], [ProjectId])
VALUES (1, 2)
SELECT
[RowCount] = ##RowCount,
[##IDENTITY] = ##IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
Result:
RowCount ##IDENTITY SCOPE_IDENTITY
1 24 24
INSERT [dbo].[ComponentAssociation]([EcuId], [ComponentId])
VALUES(1, 2)
SELECT
[RowCount] = ##RowCount,
[##IDENTITY] = ##IDENTITY,
[SCOPE_IDENTITY] = SCOPE_IDENTITY()
Result:
RowCount ##IDENTITY SCOPE_IDENTITY
1 613 NULL
OK, the issue is solved.
Found the solution here: error when inserting into table having instead of trigger from entity data framework
I added the following select statement at the end of the instead of insert,update trigger returning all the computed columns:
select [Id], [CreationDate], [LastModificationDate] from {0}.[dbo].[ComponentAssociation] where ##ROWCOUNT > 0 and Id = scope_identity()

Insert new record with composite primary key, which consists of two foreign keys from different tables

Please help me figure out how to Insert new record with composite primary key, which consists of two foreign keys from different tables.
I am working in C#, WPF if that matters.
I have three tables: Sales, SaleItem, Item.
CREATE TABLE [dbo].[Sales] (
[saleID] INT IDENTITY (1, 1) NOT NULL,
[saleTime] DATETIME NOT NULL,
[customerID] INT NULL,
[TIN] INT NOT NULL,
CONSTRAINT [PK_Sales] PRIMARY KEY CLUSTERED ([saleID] ASC),
CONSTRAINT [FK_Sales_Customers] FOREIGN KEY ([customerID]) REFERENCES [dbo].[Customers] ([customerID]),
CONSTRAINT [FK_Sales_Company] FOREIGN KEY ([TIN]) REFERENCES [dbo].[Company] ([TIN])
);
CREATE TABLE [dbo].[Item] (
[ItemSKU] INT IDENTITY (1, 1) NOT NULL,
[itemName] NVARCHAR (50) NOT NULL,
[volume] FLOAT (53) NOT NULL,
[measureUnit] NVARCHAR (50) NOT NULL,
[producer] NVARCHAR (50) NOT NULL,
[supplierID] INT NOT NULL,
[retailPrice] NUMERIC (18) NOT NULL,
CONSTRAINT [PK_Item] PRIMARY KEY CLUSTERED ([ItemSKU] ASC),
CONSTRAINT [FK_Item_Suppliers] FOREIGN KEY ([supplierID]) REFERENCES [dbo].[Suppliers] ([supplierID])
);
CREATE TABLE [dbo].[SaleItem] (
[saleID] INT IDENTITY (1, 1) NOT NULL,
[itemSKU] INT NOT NULL,
[quantity] INT NOT NULL,
CONSTRAINT [PK_SaleItem] PRIMARY KEY CLUSTERED ([saleID] ASC, [itemSKU] ASC),
CONSTRAINT [FK_SaleItem_Sales] FOREIGN KEY ([saleID]) REFERENCES [dbo].[Sales] ([saleID]),
CONSTRAINT [FK_SaleItem_Item] FOREIGN KEY ([itemSKU]) REFERENCES [dbo].[Item] ([ItemSKU])
);
I want to insert a new record into SaleItem table (the third one) where saleID is the last ID recorded in Sales table and ItemSKU which is equal to the value I get from another window.
I want these values:
SaleID = SELECT TOP 1 saleID FROM Sales ORDER BY saleID DESC";
ItemSKU = "SELECT itemName FROM Item WHERE ItemSKU = #sku";
I think I must do it in one query but I have no idea how.
Can you please give me a hint? I
First, you need to remove the IDENTITY property from the dbo.SaleItem table. The IDENTITY property is only required on the parent table, dbo.Sales.
You can do a single INSERT statement like this. It uses two subqueries, which are the SELECT statements in parentheses, to get values from the other two tables.
INSERT INTO dbo.SaleItem (saleID, itemSKU, quantity)
VALUES ((SELECT MAX(saleID) FROM dbo.Sales),
(SELECT ItemSKU FROM dbo.Item WHERE itemName = N'Widget'),
50);
You might want to turn it into a stored procedure, like this:
CREATE PROCEDURE dbo.up_InsertSaleItem
(
#itemName nvarchar(50),
#quantity int
)
AS
INSERT INTO dbo.SaleItem (saleID, itemSKU, quantity)
VALUES ((SELECT MAX(saleID) FROM dbo.Sales),
(SELECT ItemSKU FROM dbo.Item WHERE itemName = #itemName),
#quantity);
Then to use the stored procedure:
-- Test the stored procedure
EXEC dbo.up_InsertSaleItem #itemName=N'Widget', #quantity=50;
SELECT *
FROM dbo.SaleItem;
To read more about subqueries, see Microsoft SQL Server 2012 T-SQL Fundamentals by Itzik Ben-Gan, Chapter 4: Subqueries.

relationships between tables in sql server

I have one table with 6 columns. I have another 6 tables with two columns.Each of these 6 tables have id column and value column.These 6 tables are dropdowns in my app, and I want now each value from dropdown e.g from one table of these 6 to be referenced somehow with first table which has 6 columns that supposed to be ID foreach of these 6 columns ID.I trying with hours but I cant reference these tables.E.g when user pick some value from dropdown, how first table with six columns to know what value is selected from another table.Could anyone help me here?Thanks
Welcome to StackOverflow!
If I got you right (I hope so), you want to create one table containing foreign-key columns referencing to the Dropdown values. So, each row contains 6 dropdown values.
Is this what you're looking for?
--Data Tables
CREATE TABLE [DropDownTable1]
(
[DropDownTable1Id] INT Identity(1,1) NOT NULL,
[Name] VARCHAR(32) NOT NULL,
CONSTRAINT [pk__dropdowntable1] PRIMARY KEY CLUSTERED ([DropDownTable1Id] ASC)
);
CREATE TABLE [DropDownTable2]
(
[DropDownTable2Id] INT Identity(1,1) NOT NULL,
[Name] VARCHAR(32) NOT NULL,
CONSTRAINT [pk__dropdowntable2] PRIMARY KEY CLUSTERED ([DropDownTable2Id] ASC)
);
CREATE TABLE [DropDownTable3]
(
[DropDownTable3Id] INT Identity(1,1) NOT NULL,
[Name] VARCHAR(32) NOT NULL,
CONSTRAINT [pk__dropdowntable3] PRIMARY KEY CLUSTERED ([DropDownTable3Id] ASC)
);
CREATE TABLE [DropDownTable4]
(
[DropDownTable4Id] INT Identity(1,1) NOT NULL,
[Name] VARCHAR(32) NOT NULL,
CONSTRAINT [pk__dropdowntable4] PRIMARY KEY CLUSTERED ([DropDownTable4Id] ASC)
);
CREATE TABLE [DropDownTable5]
(
[DropDownTable5Id] INT Identity(1,1) NOT NULL,
[Name] VARCHAR(32) NOT NULL,
CONSTRAINT [pk__dropdowntable5] PRIMARY KEY CLUSTERED ([DropDownTable5Id] ASC)
);
CREATE TABLE [DropDownTable6]
(
[DropDownTable6Id] INT Identity(1,1) NOT NULL,
[Name] VARCHAR(32) NOT NULL,
CONSTRAINT [pk__dropdowntable6] PRIMARY KEY CLUSTERED ([DropDownTable6Id] ASC)
);
--Table with relations
CREATE TABLE [TbWithSixColumns]
(
[TbWithSixColumnsId] INT Identity(1,1) NOT NULL,
[DropDownTable1Id] INT NOT NULL,
[DropDownTable2Id] INT NOT NULL,
[DropDownTable3Id] INT NOT NULL,
[DropDownTable4Id] INT NOT NULL,
[DropDownTable5Id] INT NOT NULL,
[DropDownTable6Id] INT NOT NULL,
CONSTRAINT [pk__tbwithsixcolumns] PRIMARY KEY CLUSTERED ([TbWithSixColumnsId] ASC),
CONSTRAINT [fk__tbwithsixcolumns__dropdowntable1id] FOREIGN KEY([DropDownTable1Id]) REFERENCES [DropDownTable1]([DropDownTable1Id]),
CONSTRAINT [fk__tbwithsixcolumns__dropdowntable2id] FOREIGN KEY([DropDownTable2Id]) REFERENCES [DropDownTable2]([DropDownTable2Id]),
CONSTRAINT [fk__tbwithsixcolumns__dropdowntable3id] FOREIGN KEY([DropDownTable3Id]) REFERENCES [DropDownTable3]([DropDownTable3Id]),
CONSTRAINT [fk__tbwithsixcolumns__dropdowntable4id] FOREIGN KEY([DropDownTable4Id]) REFERENCES [DropDownTable4]([DropDownTable4Id]),
CONSTRAINT [fk__tbwithsixcolumns__dropdowntable5id] FOREIGN KEY([DropDownTable5Id]) REFERENCES [DropDownTable5]([DropDownTable5Id]),
CONSTRAINT [fk__tbwithsixcolumns__dropdowntable6id] FOREIGN KEY([DropDownTable6Id]) REFERENCES [DropDownTable6]([DropDownTable6Id])
);
--Populate Test-Data
INSERT INTO [DropDownTable1] ([Name]) VALUES ('Dropdownentry 1.1')
INSERT INTO [DropDownTable2] ([Name]) VALUES ('Dropdownentry 2.1')
INSERT INTO [DropDownTable3] ([Name]) VALUES ('Dropdownentry 3.1')
INSERT INTO [DropDownTable4] ([Name]) VALUES ('Dropdownentry 4.1')
INSERT INTO [DropDownTable5] ([Name]) VALUES ('Dropdownentry 5.1')
INSERT INTO [DropDownTable6] ([Name]) VALUES ('Dropdownentry 6.1')
INSERT INTO [TbWithSixColumns] ([DropDownTable1Id],[DropDownTable2Id],[DropDownTable3Id],[DropDownTable4Id],[DropDownTable5Id],[DropDownTable6Id]) VALUES (1,1,1,1,1,1);
--Query the dropdown data
SELECT t1.Name, t2.Name, t3.Name, t4.Name, t5.Name, t6.Name
FROM [TbWithSixColumns] relationTb
INNER JOIN [DropDownTable1] t1 ON relationTb.DropDownTable1Id = t1.DropDownTable1Id
INNER JOIN [DropDownTable2] t2 ON relationTb.DropDownTable2Id = t2.DropDownTable2Id
INNER JOIN [DropDownTable3] t3 ON relationTb.DropDownTable3Id = t3.DropDownTable3Id
INNER JOIN [DropDownTable4] t4 ON relationTb.DropDownTable4Id = t4.DropDownTable4Id
INNER JOIN [DropDownTable5] t5 ON relationTb.DropDownTable5Id = t5.DropDownTable5Id
INNER JOIN [DropDownTable6] t6 ON relationTb.DropDownTable6Id = t6.DropDownTable6Id
Please notice:
When asking questions, be as specific as you can and provide as much details as possible (We really appreciate Code Snippets, Data-Models and Images that help to describe your problem). The more details you provide, the more we are able to fully understand where you got stuck. Further, it is much easier for us, if we don't have to build a whole solution from scratch. (And, since developers are lazy, you also increase the probability that someone answers ;)
I hope I could help you.

Is this a bug in MERGE, failing to implement FOREIGN KEY properly?

I am using the following tables to implement subtypes, which is a very common approach:
CREATE TABLE dbo.Vehicles(
ID INT NOT NULL,
[Type] VARCHAR(5) NOT NULL,
CONSTRAINT Vehicles_PK PRIMARY KEY(ID),
CONSTRAINT Vehicles_UNQ_ID_Type UNIQUE(ID, [Type]),
CONSTRAINT Vehicles_CHK_ValidTypes CHECK([Type] IN ('Car', 'Truck'))
);
GO
CREATE TABLE dbo.Cars(ID INT NOT NULL,
[Type] AS CAST('Car' AS VARCHAR(5)) PERSISTED,
OtherData VARCHAR(10) NULL,
CONSTRAINT Cars_PK PRIMARY KEY(ID),
CONSTRAINT Cars_FK_Vehicles FOREIGN KEY(ID, [Type])
REFERENCES dbo.Vehicles(ID, [Type])
);
GO
-- adding parent rows
INSERT INTO dbo.Vehicles(ID, [Type])
VALUES(1, 'Car'),
(2, 'Truck');
I have no problem adding a child row via INSERT, as follows:
INSERT INTO dbo.Cars(ID, OtherData)
VALUES(1, 'Some Data');
DELETE FROM dbo.Cars;
Surprisingly, MERGE fails to add one child row:
MERGE dbo.Cars AS TargetTable
USING
( SELECT 1 AS ID ,
'Some Data' AS OtherData
) AS SourceData
ON SourceData.ID = TargetTable.ID
WHEN NOT MATCHED
THEN INSERT (ID, OtherData)
VALUES(SourceData.ID, SourceData.OtherData);
Msg 547, Level 16, State 0, Line 1
The MERGE statement conflicted with the FOREIGN KEY constraint "Cars_FK_Vehicles". The conflict occurred in database "Test", table "dbo.Vehicles".
The statement has been terminated.
Is this a bug in MERGE or am I missing something?
Looks like a definite bug in MERGE to me.
The execution plan has the Clustered Index Merge operator and is supposed to output [Cars].ID,[Cars].Type for validation against the Vehicles table.
Experimentation shows that instead of passing the value "Car" as the Type value it is passing an empty string. This can be seen by removing the check constraint on Vehicles then inserting
INSERT INTO dbo.Vehicles(ID, [Type]) VALUES (3, '');
The following statement now works
MERGE dbo.Cars AS TargetTable
USING
( SELECT 3 AS ID ,
'Some Data' AS OtherData
) AS SourceData
ON SourceData.ID = TargetTable.ID
WHEN NOT MATCHED
THEN INSERT (ID, OtherData)
VALUES(SourceData.ID, SourceData.OtherData);
But the end result is that it inserts a row violating the FK constraint.
Cars
ID Type OtherData
----------- ----- ----------
3 Car Some Data
Vehicles
ID Type
----------- -----
1 Car
2 Truck
3
Checking the constraints immediately afterwards
DBCC CHECKCONSTRAINTS ('dbo.Cars')
Shows the offending row
Table Constraint Where
------------- ------------------- ------------------------------
[dbo].[Cars] [Cars_FK_Vehicles] [ID] = '3' AND [Type] = 'Car'

What is the proper procedure when trying to test your database in SQL?

I'm pretty new to databases and I have this assignment that I've completed where I had to look at a merged Entity Relationship Diagram and then create Drop Tables, Tables (with constraints and identity's), Alterations and Indexes. I'm pretty sure I've coded everything correctly but the only area I'm a little unsure about, it's how to test that the database will actually function when executing it. My instructor gave me a TestData.sql file that I just have to refer to the database and then execute and it should insert all the data into the tables and drop everything correctly. I have it all hooked up properly on SQL Server Management Studio but I forget what steps I should be taking in order to test the proper execution of the tables. I'll post some of my code so you guys can take a look. Any information regarding this issue would be greatly appreciated!
Also, when it says in the Test Data SQL code "IMPORTANT! If you need to run this script more than once you must drop and recreate your tables first to reset the identity properties." --Does this mean that if I run into any errors while trying to execute the test data, I will have to execute the DROP TABLES first and then maybe copy and paste all the TABLES back into the Database file? I don't actually have to manually type all the TABLES again, just need to re-enter them as "new" so the system will kind of reset it's identity properties?
If you guys need me to post more of the code for clarification, just let me know. Thanks for taking the time to read this :)
Update: I'm getting 2 error messages when trying to execute the TestData script: "Invalid object name 'SaleDetail'." and "Invalid object name 'Author'." I've also provided the rest of the code from my Database script file for you to take a look at. I'm almost certain everything is correct.
Database Tables Code (this is the complete code script)
USE Lab2A_BooksGalore
GO
/*------ Drop Table Statements ------*/
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'SaleDetail')
DROP TABLE SaleDetail
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'AuthorTitle')
DROP TABLE AuthorTitle
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Title')
DROP TABLE Title
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Publisher')
DROP TABLE Publisher
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Category')
DROP TABLE Category
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Author')
DROP TABLE Author
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Sale')
DROP TABLE Sale
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Employee')
DROP TABLE Employee
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'Customer')
DROP TABLE Customer
/*------- Create Table Statements -------*/
CREATE TABLE Customer
(
CustomerNumber int
CONSTRAINT PK_Customer_CustomerNumber
PRIMARY KEY
IDENTITY (1, 1) NOT NULL,
LastName varchar(30) NOT NULL,
FirstName varchar(30) NOT NULL,
[Address] varchar(40) NULL,
City varchar(30) NULL,
Province char(2)
CONSTRAINT DF_Customer_Province
DEFAULT ('AB') NULL,
PostalCode char(6)
CONSTRAINT CK_Customer_PostalCode
CHECK (PostalCode LIKE '[A-Z][0-9][A-Z][0-9][A-Z][0-9]')
NULL,
HomePhone char(10)
)
CREATE TABLE Employee
(
EmployeeNumber int
CONSTRAINT PK_Employee_EmployeeNumber
PRIMARY KEY
IDENTITY (300, 1) NOT NULL,
[SIN] char(9) NOT NULL,
LastName varchar(30) NOT NULL,
FirstName varchar(30) NOT NULL,
[Address] varchar(40) NULL,
City varchar(20) NULL,
Province char(2)
CONSTRAINT DF_Employee_Province
DEFAULT ('AB') NULL,
PostalCode char(6)
CONSTRAINT CK_Employee_PostalCode
CHECK (PostalCode LIKE '[A-Z][0-9][A-Z][0-9][A-Z][0-9]')
NULL,
HomePhone char(10) NULL,
WorkPhone char(10) NULL,
Email varchar(40) NULL,
)
CREATE TABLE Sale
(
SaleNumber int
CONSTRAINT PK_Sale_SaleNumber
PRIMARY KEY
IDENTITY (3000, 1) NOT NULL,
SaleDate datetime NOT NULL,
CustomerNumber int
CONSTRAINT FK_Sale_CustomerNumber_Customer_CustomerNumber
FOREIGN KEY REFERENCES Customer(CustomerNumber)
NOT NULL,
EmployeeNumber int
CONSTRAINT FK_Sale_EmployeeNumber_Employee_EmployeeNumber
FOREIGN KEY REFERENCES Employee(EmployeeNumber)
NOT NULL,
Subtotal money
CONSTRAINT CK_Sale_Subtotal
CHECK (Subtotal <= Total) NOT NULL,
GST money NOT NULL,
Total money
CONSTRAINT CK_Sale_Total
CHECK (Total >= Subtotal) NOT NULL,
)
CREATE TABLE Author
(
AuthorCode int
CONSTRAINT PK_Author_AuthorCode
PRIMARY KEY
IDENTITY (100, 1) NOT NULL,
LastName varchar(30) NOT NULL,
FirstName varchar(30) NOT NULL,
)
CREATE TABLE Category
(
CategoryCode int
CONSTRAINT PK_Category_CategoryCode
PRIMARY KEY
IDENTITY (1, 1) NOT NULL,
[Description] varchar(40) NOT NULL,
)
CREATE TABLE Publisher
(
PublisherCode int
CONSTRAINT PK_Publisher_PublisherCode
PRIMARY KEY
IDENTITY (200, 1) NOT NULL,
[Name] varchar(40) NOT NULL,
)
CREATE TABLE Title
(
ISBN char(10)
CONSTRAINT PK_Title_ISBN
PRIMARY KEY NOT NULL,
Title varchar(40) NOT NULL,
SuggestedPrice smallmoney
CONSTRAINT DF_Title_SuggestedPrice
DEFAULT (0) NOT NULL,
NumberInStock smallint
CONSTRAINT CK_Title_NumberInStock
CHECK (NumberInStock >= 0)
CONSTRAINT DF_Title_NumberInStock
DEFAULT (0) NOT NULL,
PublisherCode int
CONSTRAINT FK_Title_PublisherCode_Publisher_PublisherCode
FOREIGN KEY REFERENCES Publisher(PublisherCode)
NOT NULL,
CategoryCode int
CONSTRAINT FK_Title_CategoryCode_Category_CategoryCode
FOREIGN KEY REFERENCES Category(CategoryCode)
NOT NULL,
)
CREATE TABLE AuthorTitle
(
ISBN char(10)
CONSTRAINT FK_AuthorTitle_ISBN_Title_ISBN
FOREIGN KEY REFERENCES Title(ISBN)
NOT NULL,
AuthorCode int
CONSTRAINT FK_AuthorTitle_AuthorCode_Author_AuthorCode
FOREIGN KEY REFERENCES Author(AuthorCode)
NOT NULL,
)
CREATE TABLE SaleDetail
(
SaleNumber int
CONSTRAINT FK_SaleDetail_SaleNumber_Sale_SaleNumber
FOREIGN KEY REFERENCES Sale(SaleNumber)
NOT NULL,
ISBN char(10)
CONSTRAINT FK_SaleDetail_ISBN_Title_ISBN
FOREIGN KEY REFERENCES Title(ISBN)
NOT NULL,
SellingPrice money NOT NULL,
Quantity int NOT NULL,
Amount money NOT NULL,
)
/*----------------- Alter Table Statements --------------------*/
---1) Add a char(10) attribute named WorkPhone to the Customer Table
ALTER TABLE Customer
ADD WorkPhone char(10) NULL
GO
---2) Add a varchar(30) attribute named Email to the Customer Table
ALTER TABLE Customer
ADD Email varchar(30) NULL
GO
---3) Add a constraint to make sure the correct format is followed for the Email attribute
ALTER TABLE Customer
ADD CONSTRAINT CK_Customer_Email
CHECK (Email LIKE '[a-z, 0-9][a-z, 0-9][a-z, 0-9]%#[a-z, 0-9][a-z, 0-9][a-z, 0-9]%.[a-z, 0-9][a-z, 0-9]%')
--- Match For: b 8 l # g v t . c a
GO
---4) Add a char(1) attribute named Active that's required for the Employee Table
ALTER TABLE Employee
ADD Active char(1) NOT NULL
GO
---5) Add a constraint to make sure the default character is used for the Active attribute
ALTER TABLE Employee
ADD CONSTRAINT DF_Employee_Active
DEFAULT ('y')
GO
/*------------------ Foreign Key Index Statements -----------------*/
CREATE NONCLUSTERED INDEX IX_Sale_CustomerNumber
ON Sale (CustomerNumber)
CREATE NONCLUSTERED INDEX IX_Sale_EmployeeNumber
ON Sale (EmployeeNumber)
CREATE NONCLUSTERED INDEX IX_Title_PublisherCode
ON Title (PublisherCode)
CREATE NONCLUSTERED INDEX IX_Title_CategoryCody
ON Title (CategoryCode)
CREATE NONCLUSTERED INDEX IX_AuthorTitle_ISBN
ON AuthorTitle (ISBN)
CREATE NONCLUSTERED INDEX IX_AuthorTitle_AuthorCode
ON AuthorTitle (AuthorCode)
CREATE NONCLUSTERED INDEX IX_SaleDetail_SaleNumber
ON SaleDetail (SaleNumber)
CREATE NONCLUSTERED INDEX IX_SaleDetail_ISBN
ON SaleDetail (ISBN)
GO
Test Data Code(this is only a snippet being this script is 100% accurate - provided by instructor)
USE Lab2A_BooksGalore
GO
--Lab 2 insert script
--IMPORTANT! If you need to run this script more than once you must drop and recreate your tables first to reset the identity properties.
--Delete existing data in the tables, if there is any
Delete From SaleDetail
Delete From Sale
Delete From AuthorTitle
Delete From Title
Delete From Employee
Delete From Customer
Delete From Category
Delete From Publisher
Delete From Author
Go
Insert into Author
(LastName, FirstName)
Values
('Smith', 'Sammy'),
('Greens', 'George'),
('Jones', 'Johnny'),
('Davidson', 'David'),
('Robertson', 'Rob'),
('Abbots', 'Abe'),
('Bakers', 'Bob'),
('Caters', 'Clem'),
('Semenko', 'Dave'),
('Franky', 'Fran'),
('Horton', 'Harry'),
('Kelly', 'Kevin'),
('Lambert', 'Larry'),
('Johnson', 'Jon'),
('Anderson', 'Ander'),
('Peterson', 'Peter'),
('Jensen', 'Jens'),
('Issacsen', 'Issac')
Insert into Publisher
(Name)
Values
('Addison Westley'),
('SAMS'),
('Harlequin'),
('Self Publish Inc'),
('Microsoft Press'),
('Jones and Bartlett'),
('WROX'),
('West'),
('Premier')
Insert into Category
(Description)
Values
('Computers'),
('Business'),
('Human Relation'),
('Electronics'),
('Designs'),
('Miscellaneous'),
('Media Design'),
('Information Technologies')

Resources