IF EXISTS logic to create new table and/or columns - sql-server

My goal is to make two if statements in SQL that check if a table and a column exist.
My first if statement is returning an error that says:
the table exists with the name.
In my second statement I don't know how to check if a column is already there/not there.
First SQL statement:
USE [Elearn2]
GO
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[GDPR_SupportRequest]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[GDPR_SupportRequest]
(
[Id] [uniqueidentifier] NOT NULL,
[RequestDate] [datetime2](7) NOT NULL,
[RequestType] [nvarchar](max) NOT NULL,
[RequestQuery] [nvarchar](max) NOT NULL,
[UserId] [uniqueidentifier] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
ALTER TABLE [dbo].[GDPR_SupportRequest] WITH CHECK
ADD FOREIGN KEY([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id])
END
Second SQL statement:
IF EXISTS (SELECT * FROM UserMetaData WHERE Consent != Null)
BEGIN
ALTER TABLE UserMetaData
ADD Consent BIT NULL DEFAULT 0;
END
If someone could help me to fix the statement please let me know how.
Thank you

You are checking whether the table GDPR_SupportRequest exists and creating the table if it exists, instead you should create it if the table GDPR_SupportRequest doesn't exists already.
USE [Elearn2]
GO
IF NOT EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[GDPR_SupportRequest]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[GDPR_SupportRequest]
(
[Id] [uniqueidentifier] NOT NULL,
[RequestDate] [datetime2](7) NOT NULL,
[RequestType] [nvarchar](max) NOT NULL,
[RequestQuery] [nvarchar](max) NOT NULL,
[UserId] [uniqueidentifier] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
ALTER TABLE [dbo].[GDPR_SupportRequest] WITH CHECK
ADD FOREIGN KEY([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id])
END
You can use the below script to check if the column Consent exists in the table UserMetaData and if the column doesn't then you can add it.
IF NOT EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'UserMetaData'
AND COLUMN_NAME = 'Consent')
BEGIN
ALTER TABLE UserMetaData
ADD Consent BIT NULL DEFAULT 0;
END

Related

MS SQL Constraint on a column

I have a table called Products this is how it looks like and I am trying to create a constraint on [IsDefaultProductKey] column, that any time a value is added to it, it needs be an active product key.
CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](64) NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDefaultProductKey] [int] NULL,
CONSTRAINT [PK_dbo.Products] PRIMARY KEY CLUSTERED
(
[ProductId] 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].[Products] ADD CONSTRAINT [DF_products_IsActive] DEFAULT ((1)) FOR [IsActive]
GO
ALTER TABLE [dbo].[Products] WITH CHECK ADD CONSTRAINT [FK_Products_Product_IsDefaultProductKey] FOREIGN KEY([IsDefaultProductKey])
REFERENCES [dbo].[Products] ([ProductId])
GO
ALTER TABLE [dbo].[Products] CHECK CONSTRAINT [FK_Products_Product_IsDefaultProductKey]
GO
If these are the entries in the table, row 4 should not be allowed to have a value of 1, since 1 is inactive. How can I go about adding a constraint on the table for that
ProductId Name IsActive IsDefaultProductKey
1 Test1 0 NULL
2 Test2 1 NULL
3 Test3 0 2
4 Test4 0 1 (Should not let me do this)
Based on suggestion, I created this UDF. But still not acting 100% the way I want it.. Please suggest.
CREATE TABLE [dbo].[Products]( [ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](64) NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDefaultProductKey] [int] NULL,
)
go
Create FUNCTION dbo.CheckProduct (#IsDefaultProductKey int)
RETURNS int
AS
BEGIN
DECLARE #retval int
SELECT #retval = 0
Select #retval = 1
FROM [Products]
WHERE ProductId = #IsDefaultProductKey and IsActive = 1
RETURN #retval
END;
GO
--Select CheckProduct(1)
ALTER TABLE [Products]
ADD CONSTRAINT chkActiveProduct
CHECK (IsDefaultProductKey = null or dbo.CheckProduct(IsDefaultProductKey) = 1);
go
You can use a CHECK CONSTRAINT that calls a UDF that queries the table to see if the ProductId referenced by IsDefaultProductKey is Active or not.
EDIT:
Since you need the constraint to check both ways, you would create a UDF that has parameters for ProductId, IsActive and IsDefaultProductKey.
Inside the function, if there is a non-NULL value for IsDefaultProductKey, then you need to query the table to see if the row with that ProductId is Active. If not, then the function needs to return false.
ALSO, if the IsActive parameter is passed a value of 0, then you need to check the table to make sure that no row has a IsDefaultProductKey equal to the value of the ProductId parameter. If there is such a row, then the function needs to return false.
But if neither of those cases occur, the function returns true, and in the CHECK CONSTRAINT, you then just test to see if the function returns true.
I did not understand your questions completely. However looks like you want to apply a check constraint based on the value of other column. The issue which I see in your SQL is you are applying a column level constraint, while I think you need to apply a table level constraint. Please see below sample based on my understanding of your question.
CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](64) NOT NULL,
[IsActive] [bit] NOT NULL,
[IsDefaultProductKey] [int] NULL,
CONSTRAINT ck_contraint CHECK
(
(IsActive = 1 AND (IsDefaultProductKey>0) )
)
)
I think you need a trigger not a constraint to do this. Something like:
CREATE OR ALTER TRIGGER DefaultNotActive ON [dbo].[Products]
AFTER INSERT, UPDATE
AS
IF EXISTS (SELECT *
FROM [dbo].[Products] p
JOIN inserted AS i
ON p.[ProductId] = i.[IsDefaultProductKey]
WHERE p.[IsActive] = 0
)
BEGIN
RAISERROR ('Default Product is inactive.', 16, 1);
ROLLBACK TRANSACTION;
RETURN
END;
It might need to be more complex if you also need the default product key to exist. Currently this will allow inserts\updates where the default product key is an id that does not have an existing row in the table
Thanks to Tab Allemnan, Here is the solution I found. Works both ways.
Create FUNCTION CheckProduct (#IsDefaultProductKey int, #ProductId int, #IsActive bit)
RETURNS bit
AS
BEGIN
BEGIN
DECLARE #ret bit;
if (#IsDefaultProductKey is not NULL)
begin
SELECT #ret = 1
FROM [Products] p
WHERE p.ProductID = #IsDefaultProductKey
AND p.IsActive = 1;
end
else -- If #IsDefaultProductKey is null
Select #ret = 1
If (#IsActive = 0) -- If Product is made inactive, make sure that its not a defaultkey for any product.
Begin
SELECT #ret = 0
FROM [Products] p
WHERE p.IsDefaultProductKey = #ProductId
End
IF (#ret IS NULL)
SET #ret = 0;
RETURN #ret;
END;
END;
--Select dbo.CheckProduct (2,1,0)
GO
ALTER TABLE [Products]
ADD CONSTRAINT chkActiveProduct
CHECK (dbo.CheckProduct(IsDefaultProductKey,ProductId, IsActive)=1);
go

SQL Server stored procedure with geolocation not returning data

I have written the following stored procedure to return data based on a lat/long and category id being passed.
I need to return a list of traders whose coverage area falls within the passed lat long (and that they cover the category being passed). So I am looking to draw a circle around the traders lat/long position, x number of meters using the radius they will operate from (this is stored in the Traders.OperatingRadius column). If the passed lat long coord is within this, then they should be included in the return list.
CREATE PROCEDURE FindTradersWithinRadiusLatLong
#LAT decimal(9,6),
#LONG decimal(9,6),
#CATEGORY int
AS
BEGIN
SET NOCOUNT ON;
DECLARE #GEO1 GEOGRAPHY;
SET #GEO1 = geography::Point(#LAT, #LONG, 4326)
SELECT
x.Id, x.Name,
x.Latitude, x.Longitude,
x.Distance, x.IsArchived
FROM
(SELECT
Traders.Id, Traders.Name,
Latitude, Longitude,
CategoryId = TraderCategories.Id,
OperatingRadius,
Traders.IsArchived,
Distance = (#geo1.STDistance(geography::Point(ISNULL(Latitude, 0), ISNULL(Longitude, 0), 4326)))
FROM
((Addresses
INNER JOIN
Traders ON Addresses.TraderId = Traders.Id)
INNER JOIN
TraderCategories ON Traders.Id = TraderCategories.TraderId)) AS x
WHERE
x.Distance <= x.OperatingRadius
AND x.CategoryId = #CATEGORY
AND (x.IsArchived = 0 OR x.IsArchived = NULL);
END
GO
TraderCategories is a linking table as follows;
Table TraderCategories
int FK TraderId
int FK CategoryId
Now I have added an address with;
latitiude - 43.590000, Longitude - -111.120000
There is also a TraderCategory Relationship for category with Id 1
I have then tried calling the stored procedure with the above and no matches are being returned.
The table definitions are as follows:
CREATE TABLE [Bemfeito].[Addresses]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Address1] [nvarchar](max) NULL,
[Address2] [nvarchar](max) NULL,
[Address3] [nvarchar](max) NULL,
[TraderId] [int] NULL,
[Latitude] [decimal](9, 6) NOT NULL,
[Longitude] [decimal](9, 6) NOT NULL,
[OperatingRadius] [real] NOT NULL DEFAULT (CONVERT([real],(0)))
CONSTRAINT [PK_Addresses]
PRIMARY KEY CLUSTERED ([Id] ASC)
)
GO
ALTER TABLE [Bemfeito].[Addresses] WITH CHECK
ADD CONSTRAINT [FK_Addresses_Traders_TraderId]
FOREIGN KEY([TraderId]) REFERENCES [Bemfeito].[Traders] ([Id])
GO
ALTER TABLE [Bemfeito].[Addresses] CHECK CONSTRAINT [FK_Addresses_Traders_TraderId]
GO
CREATE TABLE [Bemfeito].[Traders]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Email] [nvarchar](max) NULL
[Name] [nvarchar](max) NULL
CONSTRAINT [PK_Traders]
PRIMARY KEY CLUSTERED ([Id] ASC)
)
GO
CREATE TABLE [Bemfeito].[TraderCategories]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[CategoryId] [int] NULL,
[TraderId] [int] NULL,
CONSTRAINT [PK_TraderCategories]
PRIMARY KEY CLUSTERED ([Id] ASC)
)
GO
ALTER TABLE [Bemfeito].[TraderCategories] WITH CHECK
ADD CONSTRAINT [FK_TraderCategories_Categories_CategoryId]
FOREIGN KEY([CategoryId]) REFERENCES [Bemfeito].[Categories] ([Id])
GO
ALTER TABLE [Bemfeito].[TraderCategories] CHECK CONSTRAINT [FK_TraderCategories_Categories_CategoryId]
GO
ALTER TABLE [Bemfeito].[TraderCategories] WITH CHECK
ADD CONSTRAINT [FK_TraderCategories_Traders_TraderId]
FOREIGN KEY([TraderId]) REFERENCES [Bemfeito].[Traders] ([Id])
GO
ALTER TABLE [Bemfeito].[TraderCategories] CHECK CONSTRAINT [FK_TraderCategories_Traders_TraderId]
GO
and finally for completion the category
CREATE TABLE [Bemfeito].[Categories]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Value] [int] NOT NULL,
CONSTRAINT [PK_Categories]
PRIMARY KEY CLUSTERED ([Id] ASC)
)
Can anyone tell me where I am going wrong here please?
If you look at this microsoft reference here you should notice that the argument passed to STDistance is a geometry datatype while you are passing a Point datatype.
the line currently written like this
,Distance = (#geo1.STDistance(geography::Point(ISNULL(Latitude, 0), ISNULL(Longitude, 0), 4326))
should be written as follows.
,Distance = (#geo1.STDistance(geography::STGeomFromText('Point('+ISNULL(Longitude, 0)+' '+ISNULL(Latitude, 0)')',4326))

MSSQL DateTime2 Fail to Update

Im running stored procedure which in charges to insert, update and delete table's entries.
While both insert and delete runs smoothly, the update operation updates all columns except DATETIME2 one.
The scenario - I test my Repository pattern (using C# code) in the following way:
delete the entire [BackgroundTaskAttachtment] table
Create 4 new entries
delete single entry created on step 2
Wait for 5 seconds
modify one of the entries
the result is having 3 entries in [BackgroundTaskAttachtment] table, with all properties set as expected, except the [UpdatedOnUtc] which not updated (it is equal to [CreatedOnUtc]
I marked the updated row (as you can see [FilePath] was successfully updated):
Would appreciate community insights,
Thank you
This is the stored procedure code:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP_ArrangeBackgroundTaskAttachtments]
(
#backgroundTaskId BIGINT,
#taskAttchs [dbo].[BackgroundTaskAttachtmentType] READONLY
)
AS
BEGIN
SET NOCOUNT ON;
--delete all removed attachtments
DELETE FROM [BackgroundTaskAttachtment]
WHERE [BackgroundTaskId] = #backgroundTaskId AND [Id] NOT IN (SELECT [Id] FROM #taskAttchs)
----Update exist key-value pairs
UPDATE [dbo].[BackgroundTaskAttachtment]
SET
[IsPrimary] = attachs.[IsPrimary],
[FilePath] = attachs.[FilePath],
[Bytes] = attachs.[Bytes],
[UpdatedOnUtc] = GETUTCDATE()
FROM #taskAttchs AS attachs
WHERE attachs.[Id] = [BackgroundTaskAttachtment].[Id]
--insert new records
SELECT #backgroundTaskId AS [BackgroundTaskId], [FilePath], [IsPrimary], [Bytes], GETUTCDATE() AS [CreatedOnUtc], GETUTCDATE() AS [UpdatedOnUtc]
INTO #Temp FROM #taskAttchs as atcs
WHERE atcs.[Id] NOT IN (SELECT [Id] FROM [BackgroundTaskAttachtment] AS bta WHERE bta.[BackgroundTaskId] = #backgroundTaskId )
INSERT INTO [BackgroundTaskAttachtment]([BackgroundTaskId], [IsPrimary], [Bytes], [FilePath], [CreatedOnUtc], [UpdatedOnUtc] )
SELECT [BackgroundTaskId], [IsPrimary], [Bytes], [FilePath], [CreatedOnUtc], [UpdatedOnUtc]
FROM #Temp
END
This is the table type (sent from CLR to SQL)
CREATE TYPE [dbo].[BackgroundTaskAttachtmentType] AS TABLE(
[Id] [BIGINT] NOT NULL,
[FilePath] [NVARCHAR](MAX) NULL,
[IsPrimary] [BIT] NOT NULL,
[BackgroundTaskId] [BIGINT] NULL,
[Bytes] [VARBINARY](MAX) NULL
)
GO
this is the table definition
CREATE TABLE [dbo].[BackgroundTaskAttachtment]
(
[Id] BIGINT IDENTITY(1,1) NOT NULL,
[BackgroundTaskId] BIGINT NOT NULL,
[IsPrimary] BIT NOT NULL DEFAULT 0,
[FilePath] NVARCHAR(MAX) NULL,
[Bytes] VARBINARY(MAX) NULL,
[CreatedOnUtc] DATETIME2 NOT NULL,
[UpdatedOnUtc] DATETIME2 NOT NULL,
[RowVersion] ROWVERSION NOT NULL,
CONSTRAINT [PK_dbo.BackgroundTaskAttachtment] PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_dbo.BackgroundTaskAttachtment_BackgroundTask_Id]
FOREIGN KEY ([BackgroundTaskId])
REFERENCES [dbo].[BackgroundTask] ([Id])
ON DELETE CASCADE
);
Please try using SYSUTCDATETIME which returns datetime2.
The GETUTCDATE which you are using, returns datetime.

View that joins 2 tables of similar structure will not Update (because it contains a derived or constant field)

I'm getting an error:
Msg 4406, Level 16, State 1, Line 5
Update or insert of view or function 'dbo.vwEmployeeAll' failed because it contains a derived or constant field.
Yet, I have no derived or constant in my view.
The columns in my view all exist. It's fairly straightforward in the example below.
-- START TSQL
SET NOCOUNT ON
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'vwEmployeeAll' and TABLE_TYPE = N'VIEW' )
BEGIN
DROP VIEW [dbo].[vwEmployeeAll]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[EmployeeDeprecated]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Employee]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Department' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Department]
END
GO
CREATE TABLE [dbo].[Department](
[DepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[DepartmentName] [nvarchar](80) NULL,
[CreateDate] [datetime] NOT NULL
)
ALTER TABLE dbo.[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED ([DepartmentUUID])
GO
ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE ([DepartmentName])
GO
CREATE TABLE [dbo].[Employee] (
/* [EmployeeUUID] [uniqueidentifier] NOT NULL, */
[EmployeeSurrogateKey] int not null IDENTITY(1,2),
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeSurrogateKey)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_Employee_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT FK_EmployeeToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [CK_Employee_PK_IsOdd] CHECK ( ( [EmployeeSurrogateKey] % 2 ) != 0)
GO
*/
CREATE TABLE [dbo].[EmployeeDeprecated] (
/*[EmployeeDeprecatedUUID] [uniqueidentifier] NOT NULL,*/
[EmployeeDeprecatedSurrogateKey] int not null IDENTITY(2,2),
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.[EmployeeDeprecated] ADD CONSTRAINT PK_EmployeeDeprecated PRIMARY KEY NONCLUSTERED (EmployeeDeprecatedSurrogateKey)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT CK_EmployeeDeprecated_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT FK_EmployeeDeprecatedToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[EmployeeDeprecated]
ADD CONSTRAINT [CK_EmployeeDeprecated_PK_IsEven] CHECK ( ( [EmployeeDeprecatedSurrogateKey] % 2 ) = 0)
GO
*/
CREATE VIEW dbo.vwEmployeeAll AS
Select
EmployeeSurrogateKey,ParentDepartmentUUID,TheVersionProperty,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.Employee
UNION --ALL
Select
/* EmployeeSurrogateKey = */
EmployeeDeprecatedSurrogateKey ,ParentDepartmentUUID,TheVersionProperty,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.EmployeeDeprecated
GO
declare #DepartmentUUID001 uniqueidentifier
select #DepartmentUUID001 = 'DDDDDDDD-0000-0000-0000-000000000101'
declare #DepartmentUUID002 uniqueidentifier
select #DepartmentUUID002 = 'DDDDDDDD-0000-0000-0000-000000000102'
INSERT INTO dbo.Department (DepartmentUUID , DepartmentName , CreateDate )
Select #DepartmentUUID001 , 'Department One' , CURRENT_TIMESTAMP
UNION
Select #DepartmentUUID002 , 'Department Two' , CURRENT_TIMESTAMP
/*
declare #EmployeeUUID001 uniqueidentifier
select #EmployeeUUID001 = 'EEEEEEEE-0000-0000-0000-000000001001'
declare #EmployeeUUID00A uniqueidentifier
select #EmployeeUUID00A = 'EEEEEEEE-0000-0000-AAAA-000000009001'
*/
INSERT INTO dbo.Employee (/*EmployeeUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate)
Select /*#EmployeeUUID001 ,*/ #DepartmentUUID001 , '111-11-1111' , 'Smith', 'John' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '01/01/2001'
INSERT INTO dbo.EmployeeDeprecated(/*EmployeeDeprecatedUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate)
Select /*#EmployeeUUID00A ,*/ #DepartmentUUID002 , '888-88-8888' , 'Jones', 'Mary' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '02/02/2002'
GO
Select * from dbo.vwEmployeeAll
Update dbo.vwEmployeeAll Set UpdateDate = CURRENT_TIMESTAMP
EDIT:
Timestamp throws it for a loop.
Partitioned view 'ViewUpdateableDB.dbo.vwEmployeeAll' is not updatable because table '[ViewUpdateableDB].[dbo].[Employee]' has a timestamp column.
You can't update data in a view that uses a UNION when your primary keys are Identity. You must have a Partitioning Column. Otherwise, how would it know which table to update?
IE, you are using 2 tables that have a primary key on an identity field. They could have a {PK} = 1 in both tables. How would SQL Server know which table to update.
Here is a working example...with "UNION ALL" and a Partitioning Column.
I am posting this, because there is a specific way to get it to work....despite the msdn documentation.
A computation. The column cannot be computed from an expression that
uses other columns. Columns that are formed by using the set operators
UNION, UNION ALL, CROSSJOIN, EXCEPT, and INTERSECT amount to a
computation and are also not updatable.
http://msdn.microsoft.com/en-us/library/ms187956%28v=sql.110%29.aspx
So Steve's answer is correct based on the documentation and under most scenarios, but by using a partitioning-column there is a way to make it work.
The script/example below worked with Developer Edition (which is Enterprise Version without the licensing) and I tested it against SqlExpress ( Microsoft SQL Server 2012 - 11.0.2100.60 (X64)
Express Edition (64-bit) on Windows NT 6.1 (Build 7601: Service Pack 1)
)
Select ##VERSION
-- START TSQL
SET NOCOUNT ON
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'vwEmployeeAll' and TABLE_TYPE = N'VIEW' )
BEGIN
DROP VIEW [dbo].[vwEmployeeAll]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[EmployeeDeprecated]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Employee]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Department' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Department]
END
GO
CREATE TABLE [dbo].[Department](
[DepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[DepartmentName] [nvarchar](80) NULL,
[CreateDate] [datetime] NOT NULL
)
ALTER TABLE dbo.[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED ([DepartmentUUID])
GO
ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE ([DepartmentName])
GO
CREATE TABLE [dbo].[Employee] (
/* [EmployeeUUID] [uniqueidentifier] NOT NULL, */
[EmployeeSurrogateKey] int not null IDENTITY(101,2),
[EmployeeTablePartitionOrdinal] int not null,
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
/*[TheVersionProperty] [timestamp] NOT NULL,*/
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeSurrogateKey,EmployeeTablePartitionOrdinal)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_Employee_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT FK_EmployeeToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [CK_Employee_PK_IsOdd] CHECK ( ( [EmployeeSurrogateKey] % 2 ) != 0)
GO
*/
/*
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [CK_Employee_PK_IsOdd]
CHECK ( ( [EmployeeSurrogateKey] % 2 ) != 0)
GO
*/
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [CK_EmployeeTablePartitionOrdinal_Is_One]
CHECK ( [EmployeeTablePartitionOrdinal] = 1 )
GO
CREATE TABLE [dbo].[EmployeeDeprecated] (
/*[EmployeeDeprecatedUUID] [uniqueidentifier] NOT NULL,*/
[EmployeeDeprecatedSurrogateKey] int not null IDENTITY(102,2),
[EmployeeTablePartitionOrdinal] int not null,
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
/*[TheVersionProperty] [timestamp] NOT NULL,*/ /* Partitioned view 'ViewUpdateableDB.dbo.vwEmployeeAll' is not updatable because table '[ViewUpdateableDB].[dbo].[Employee]' has a timestamp column. */
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.[EmployeeDeprecated] ADD CONSTRAINT PK_EmployeeDeprecated PRIMARY KEY NONCLUSTERED (EmployeeDeprecatedSurrogateKey,EmployeeTablePartitionOrdinal)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT CK_EmployeeDeprecated_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT FK_EmployeeDeprecatedToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[EmployeeDeprecated]
ADD CONSTRAINT [CK_EmployeeDeprecated_PK_IsEven] CHECK ( ( [EmployeeDeprecatedSurrogateKey] % 2 ) = 0)
GO
*/
/*
ALTER TABLE [dbo].[EmployeeDeprecated] WITH CHECK ADD CONSTRAINT [CK_EmployeeDeprecated_PK_IsEven]
CHECK ( ( [EmployeeDeprecatedSurrogateKey] % 2 ) = 0)
GO
*/
ALTER TABLE [dbo].[EmployeeDeprecated] WITH CHECK ADD CONSTRAINT [CK_EmployeeTablePartitionOrdinal_Is_Two]
CHECK ( [EmployeeTablePartitionOrdinal] = 2 )
GO
CREATE VIEW dbo.vwEmployeeAll AS
Select
EmployeeSurrogateKey,EmployeeTablePartitionOrdinal,ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.Employee
UNION ALL
Select
EmployeeSurrogateKey =
EmployeeDeprecatedSurrogateKey,EmployeeTablePartitionOrdinal,ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.EmployeeDeprecated
GO
declare #DepartmentUUID001 uniqueidentifier
select #DepartmentUUID001 = 'DDDDDDDD-0000-0000-0000-000000000101'
declare #DepartmentUUID002 uniqueidentifier
select #DepartmentUUID002 = 'DDDDDDDD-0000-0000-0000-000000000102'
INSERT INTO dbo.Department (DepartmentUUID , DepartmentName , CreateDate )
Select #DepartmentUUID001 , 'Department One' , CURRENT_TIMESTAMP
UNION
Select #DepartmentUUID002 , 'Department Two' , CURRENT_TIMESTAMP
/*
declare #EmployeeUUID001 uniqueidentifier
select #EmployeeUUID001 = 'EEEEEEEE-0000-0000-0000-000000001001'
declare #EmployeeUUID00A uniqueidentifier
select #EmployeeUUID00A = 'EEEEEEEE-0000-0000-AAAA-000000009001'
*/
INSERT INTO dbo.Employee (/*EmployeeUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate,EmployeeTablePartitionOrdinal)
Select /*#EmployeeUUID001 ,*/ #DepartmentUUID001 , '111-11-1111' , 'Smith', 'John' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '01/01/2001' , 1
INSERT INTO dbo.EmployeeDeprecated(/*EmployeeDeprecatedUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate,EmployeeTablePartitionOrdinal)
Select /*#EmployeeUUID00A ,*/ #DepartmentUUID002 , '888-88-8888' , 'Jones', 'Mary' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '02/02/2002' , 2
GO
Select * from dbo.vwEmployeeAll
Update dbo.vwEmployeeAll Set UpdateDate = CURRENT_TIMESTAMP
Update dbo.vwEmployeeAll Set LastName = 'Henderson' where EmployeeSurrogateKey = 1
Update dbo.vwEmployeeAll Set UpdateDate = CURRENT_TIMESTAMP where EmployeeSurrogateKey = 2

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