I have the following query
declare #var1 int, #var2 int
set #var1 = 110
set #var2 = 300
IF object_id('tempdb..#tbl_Contract') IS NOT NULL
BEGIN
ALTER TABLE #tbl_Contract drop constraint PK_#tbl_Contract
DROP TABLE #tbl_Contract
END
CREATE TABLE #tbl_Contract
( ContractID int NOT NULL
, PersonID int NOT NULL
, EndDate smalldatetime NULL
, CONSTRAINT [PK_#tbl_Contract] PRIMARY KEY CLUSTERED
(
ContractID ASC
)
)
...
But when I run this query the second time I'm getting an error:
Msg 2714, Level 16, State 5, Line 1 There is already an object named
'PK_#tbl_Contract' in the database. Msg 1750, Level 16, State 0,
Line 1 Could not create constraint. See previous errors.
What I'm doing wrong? Why my primary key was not removed?
Should I use GO after ALTER? But I can't because there are some varibles
You don't need to drop a constraint and then immediately drop the table. It is simpler to just drop the table. Also, there really is no need to name constraints in a temp table. You can greatly simplify your code like this.
IF object_id('tempdb..#tbl_Contract') IS NOT NULL
BEGIN
DROP TABLE #tbl_Contract
END
GO
CREATE TABLE #tbl_Contract
( ContractID int NOT NULL PRIMARY KEY CLUSTERED
, PersonID int NOT NULL
, EndDate smalldatetime NULL
)
For a composite primary key constraint on a temporary table it is much better not to name the primary key constraint, otherwise you will run into trouble with concurrent sessions. In the following way you can also add any number of indexes or check constraints without naming them:
IF object_id('tempdb..#tbl_Contract') IS NOT NULL
BEGIN
DROP TABLE #tbl_Contract
END
GO
CREATE TABLE #tbl_Contract
( ContractID int NOT NULL
, PersonID int NOT NULL
, EndDate smalldatetime NULL
, PRIMARY KEY CLUSTERED (ContractID ASC, PersonID ASC)
, CHECK (ContractID > 10 AND EndDate > N'2019-12-31')
)
This allows you to avoid the pitfall of #mpag's solution in that you can further use the temp table in your stored procedure. In #mpag's solution you cannot use #tbl_Contract outside the #Q statement.
You cannot create a primary key with the same name in different sessions, even on a temp table. If you do not name the primary key and other constraints, they are automatically given a different unique name by the system for each session.
Otherwise you will have the following error when concurrently running the procedure from different sessions:
Error number: 1750, error procedure:
dbo.ProcedureName, error line: XXX, error message:
Could not create constraint or index. See previous errors.
I had the same issue as #NReilingh raised in the comments (i.e. needing a composite primary key). So, lets assume we want a primary key on the combination of ContractID and PersonID. The following works in that circumstance (assuming you have appropriate permissions for EXEC):
IF object_id('tempdb..#tbl_Contract') IS NOT NULL
DROP TABLE #tbl_Contract
GO
DECLARE #Q as nvarchar(MAX) = N'
CREATE TABLE #tbl_Contract (
ContractID int NOT NULL
, PersonID int NOT NULL
, EndDate smalldatetime NULL
, CONSTRAINT
[PK_#tbl_Contract' + CAST(##SPID as nvarchar(6)) + N']
PRIMARY KEY CLUSTERED (
ContractID ASC,
PersonID ASC
)
)'
EXEC (#Q)
This works because each connection at any one time on a given server should have a unique SPID value. SPID values are typically a double-digit number greater than 50; but are of type smallint so could be up to 5 digits long, potentially signed.
Remember to double up any single quotes in within your table's DDL (i.e. replace ' with '')
Related
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()
I am having a little bit of trouble with making a trigger in my SQL. I have two tables:
This one
Create table [user]
(
[id_user] Integer Identity(1,1) NOT NULL,
[id_event] Integer NULL,
[name] Nvarchar(15) NOT NULL,
[lastname] Nvarchar(25) NOT NULL,
[email] Nvarchar(50) NOT NULL, UNIQUE ([email]),
[phone] Integer NULL, UNIQUE ([phone]),
[pass] Nvarchar(50) NOT NULL,
[nick] Nvarchar(20) NOT NULL, UNIQUE ([nick]),
Primary Key ([id_user])
)
go
and this one
Create table [event]
(
[id_event] Integer Identity(1,1) NOT NULL,
[id_creator] Integer NOT NULL,
[name] Nvarchar(50) NOT NULL,
[date] Datetime NOT NULL, UNIQUE ([date]),
[city] Nvarchar(50) NOT NULL,
[street] Nvarchar(50) NOT NULL,
[zip] Integer NOT NULL,
[building_number] Integer NOT NULL,
[n_signed_people] Integer Default 0 NOT NULL Constraint [n_signed_people] Check (n_signed_people <= 20),
Primary Key ([id_akce])
)
Now I need a trigger for when I insert a new user with and id_event, or update existing one with one, to take the id_event I inserted, look in the table of events and increment the n_signed_people in a line with a coresponding id_event, until it is 20. When it is 20, it should say that the event is full. I made something like this, it is working when I add a new user with id, but now I need it to stop at 20 and say its full and also I am not sure if it will work, when I'll try to update existing user, by adding an id_event (I assume it was NULL before update).
CREATE TRIGGER TR_userSigning
ON user
AFTER INSERT
AS
BEGIN
DECLARE #idevent int;
IF (SELECT id_event FROM Inserted) IS NOT NULL --if the id_event is not empty
BEGIN
SELECT #idevent=id_event FROM Inserted; --the inserted id_event will be save in a local variable
UPDATE event SET n_signed_people = n_signed_people+1 WHERE #idevent = id_event;
END
END
go
Good evening,
I did notice some issues with your schema. I want to list the fixes I made in order.
1 - Do not use reserved words. Both user and event are reserved.
2 - Name your constraints. You will be glad they are not some random word when you want to drop one.
3 - I added a foreign key to make sure there is integrity in the relationship.
All this work was done in tempdb. Now, lets get to the fun stuff, the trigger.
-- Just playing around
use tempdb;
go
-- attendee table
if object_id('attendees') > 0
drop table attendees
go
create table attendees
(
id int identity (1,1) NOT NULL constraint pk_attendees primary key,
firstname nvarchar(15) NOT NULL,
lastname nvarchar(25) NOT NULL,
email nvarchar(50) NOT NULL constraint uc_email unique,
phone int NULL constraint uc_phone unique,
pass nvarchar(50) NOT NULL,
nick nvarchar(20) NOT NULL constraint uc_nick unique,
event_id int NOT NULL
)
go
-- events table
if object_id('events') > 0
drop table events
go
create table events
(
id int identity (1,1) NOT NULL constraint pk_events primary key,
creator int NOT NULL,
name nvarchar(50) NOT NULL,
planed_date datetime NOT NULL constraint uc_planed_date unique,
street nvarchar(50) NOT NULL,
city nvarchar(50) NOT NULL,
zip nvarchar(9) NOT NULL,
building_num int NOT NULL,
registered int
constraint df_registered default (0) NOT NULL
constraint chk_registered check (registered <= 20),
);
go
-- add some data
insert into events (creator, name, planed_date, street, city, zip, building_num)
values (1, 'new years eve', '20131231 20:00:00', 'Promenade Street', 'Providence', '02908', 99);
-- make sure their is integrity
alter table attendees add constraint [fk_event_id]
foreign key (event_id) references events (id);
I usually add all three options (insert, update, & delete). You coded for insert in the example above. But you did not code for delete.
Also, both the inserted and deleted tables can contain multiple rows. For instance, if two attendees decide to drop out, you want to minus 2 from the table.
-- create the new trigger.
CREATE TRIGGER [dbo].[trg_attendees_cnt] on [dbo].[attendees]
FOR INSERT, UPDATE, DELETE
AS
BEGIN
-- declare local variable
DECLARE #MYMSG VARCHAR(250);
-- nothing to do?
IF (##rowcount = 0) RETURN;
-- do not count rows
SET NOCOUNT ON;
-- deleted data
IF NOT EXISTS (SELECT * FROM inserted)
BEGIN
UPDATE e
SET e.registered = e.registered - c.total
FROM
[dbo].[events] e
INNER JOIN
(SELECT [event_id], count(*) as total
FROM deleted group by [event_id]) c
ON e.id = c.event_id;
RETURN;
END
-- inserted data
ELSE IF NOT EXISTS (SELECT * FROM deleted)
BEGIN
UPDATE e
SET e.registered = e.registered + c.total
FROM
[dbo].[events] e
INNER JOIN
(SELECT [event_id], count(*) as total
FROM inserted group by [event_id]) c
ON e.id = c.event_id;
RETURN;
END;
-- updated data (no counting involved)
END
GO
Like any good programmer, I need to test my work to make sure it is sound.
Lets add 21 new attendees. The check constraint should fire. This only works since the error generated by the UPDATE rollback the insert.
-- Add 21 attendees
declare #var_cnt int = 0;
declare #var_num char(2);
while (#var_cnt < 22)
begin
set #var_num = str(#var_cnt, 2, 0);
insert into attendees (firstname, lastname, email, phone, pass, nick, event_id)
values ('first-' + #var_num,
'last-' + #var_num,
'email-'+ #var_num,
5554400 + (#var_cnt),
'pass-' + #var_num,
'nick-' + #var_num, 1);
set #var_cnt = #var_cnt + 1
end
go
Last but not least, we need to test a DELETE action.
-- Delete the last row
delete from [dbo].[attendees] where id = 20;
go
I have a table with 10 columns but only care about 3 columns for this. Imagine my table looks like this:
CREATE TABLE MyTable ( RowID int IDENTITY(1,1), UserID int, NodeID int, RoleID int )
What I need is a constraint that enforces the following: UserID and RoleID need to be unique for each NodeID (i.e. a user cannot have the same role in multiple nodes). In other words I want to allow
INSERT MyTable (UserID, NodeID, RoleID) SELECT 1, 1, 1
but not allow
INSERT MyTable (UserID, NodeID, RoleID) SELECT 1, 2, 1
if the first insert has occurred because that would result in a user having a role in multiple nodes.
Hopefully this is simple and I'm just making it more complex than it needs to be in my brain.
Since your constraint depends on data in other rows, this rules out a filtered index. IMO a viable option could be a trigger. Such a trigger could look like something like this:
CREATE TRIGGER dbo.MyTrigger ON dbo.Q1
AFTER INSERT, UPDATE
AS
DECLARE #userId INT, #Id INT, #roleId INT, #exists INT;
SELECT TOP 1
#userId = userID
,#roleId = roleID
,#Id = Id
FROM inserted;
SELECT TOP 1
#exists = Id
FROM Q1
WHERE userId = #userId
AND roleID = #roleID AND Id<> #Id;
IF ISNULL(#exists, 0) > 0
BEGIN
-- you would want to either undo the action here when you use an 'after' trigger
-- because as the name implies ... the after means the record is allready inserted/updated
RAISERROR ('No way we would allow this.', 16, 1);
END
-- else
-- begin
-- another alternative would be to use a instead of trigger, which means the record
-- has not been inserted or updated and since that type of trigger runs the trigger 'instead of'
-- updating or inserting the record you would need to do that yourself. Pick your poison ...
-- end
GO
An unique index should enforce your requirements
CREATE UNIQUE NONCLUSTERED INDEX [idx_Unique] ON [dbo].[MyTable]
(
[UserID] ASC,
[NodeID] ASC,
[RoleID] ASC
)
From the comments I suppose you will need two unique indices
CREATE UNIQUE NONCLUSTERED INDEX [idx_User_Node] ON [dbo].[MyTable]
(
[UserID] ASC,
[NodeID] ASC
)
GO
CREATE UNIQUE NONCLUSTERED INDEX [idx_User_Role] ON [dbo].[MyTable]
(
[UserID] ASC,
[RoleID] ASC
)
create table Son
(
ID int primary key identity(1,1),
DateOfBirth datetime,
constraint Age check (datediff(year,DateOfBirth,GetDate())>= 0),
Name nvarchar(50) not null check (len(Name) >= 8) default('Sergio')
)
Right now I'm just checking it he Age column is bigger than 0, how can I declare the table if the Age column is meant to be calculated?
You can introduce a computed column:
CREATE TABLE Son (
ID int primary key identity(1,1),
DateOfBirth datetime,
Age as DATEDIFF(year,DateOfBirth,GetDate()) - CASE WHEN DATEPART(month,DateOfBirth) > DATEPART(month,GetDate()) THEN 1 WHEN DATEPART(month,DateOfBirth) = DATEPART(month,GetDate()) And DATEPART(day,DateOfBirth) > DATEPART(day,GetDate()) THEN 1 ELSE 0 END
/* Other columns */
)
I think that formula's right - DATEDIFF simple measures boundary transitions (31st Dec -> 1st Jan), so you need to compare months and days also, otherwise someone born on 31st Dec is 1 year old a day later.
I would start by creating a function to calculate the age. This gives you something that is reusable on other tables as well as being able to be used in scenarios where you might want to calculate a persons age on a specific date. For example, I'm looking to throw a party later this year, and I want to know everyone that will be of legal age on that date to send them an invitation.
Then create your table and add the calculated column that references that function. Add the check constraint for the age and the length of the Given Name, etc.
You should be wary though, that by using a function, you cannot alter this function without dropping the references from the table (i.e. the computed column).
CREATE FUNCTION dbo.sfn_GetAge (#BirthDate datetime, #CalcDate datetime)
RETURNS INT
AS
BEGIN
DECLARE #theAge INT
IF Month(#CalcDate) > Month(#BirthDate )
SELECT #theAge= (Year(#CalcDate) - Year(#BirthDate ))
ELSE IF Month(#CalcDate) < Month(#BirthDate )
SELECT #theAge= ((Year(#CalcDate) - Year(#BirthDate )) - 1)
ELSE IF Day(#CalcDate) < Day(#BirthDate )
SELECT #theAge= ((Year(#CalcDate) - Year(#BirthDate )) - 1)
ELSE
SELECT #theAge= (Year(#CalcDate) - Year(#BirthDate ))
RETURN #theAge
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Son](
[ID] INT PRIMARY KEY IDENTITY(1,1),
[GivenName] [nvarchar](50) NOT NULL,
[Surname] [nvarchar](50) NOT NULL,
[DateOfBirth] [date] NOT NULL,
[Age] AS ([dbo].[sfn_GetAge]([DateOfBirth],getdate()))
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Son] ADD CONSTRAINT [DF_Son_GivenName] DEFAULT (N'Sergio') FOR [GivenName]
GO
ALTER TABLE [dbo].[Son] WITH CHECK ADD CONSTRAINT [CK_Son_Age] CHECK (([dbo].[sfn_GetAge]([DateOfBirth],getdate())>=(0)))
GO
ALTER TABLE [dbo].[Son] CHECK CONSTRAINT [CK_Son_Age]
GO
ALTER TABLE [dbo].[Son] WITH CHECK ADD CONSTRAINT [CK_Son_GivenName] CHECK ((len([GivenName])>=(8)))
GO
ALTER TABLE [dbo].[Son] CHECK CONSTRAINT [CK_Son_GivenName]
GO
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')