Very strange SQL update issue - sql

I have a table called ApprovalTasks... Approvals has a status column
I also have a view called ApprovalsView
When I try a straight update :
update ApprovalTasks set Status = 2 where ApprovalTaskID = 48
I'm getting this error message:
Msg 2601, Level 14, State 1, Line 1
Cannot insert duplicate key row in object 'dbo.ApprovalsView' with unique index 'IX_ApprovalTaskID'.
The statement has been terminated.
Any idea why this is happening?
Here is the create table script:
USE [CSPMOSSApplication]
GO
/****** Object: Table [dbo].[ApprovalTasks] Script Date: 12/11/2008 12:41:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[ApprovalTasks](
[ApprovalTaskID] [int] IDENTITY(1,1) NOT NULL,
[ApproverID] [int] NOT NULL,
[DueDate] [datetime] NULL,
[Status] [smallint] NOT NULL,
[ApprovedRejectedDate] [datetime] NULL,
[Reason] [nvarchar](1024) COLLATE Finnish_Swedish_CI_AS NULL,
[OrganizationID] [int] NOT NULL,
[TicketID] [int] NOT NULL,
[Link] [nchar](255) COLLATE Finnish_Swedish_CI_AS NULL,
[GlobalApproverID] [int] NULL,
CONSTRAINT [PK_Approval_Tasks] PRIMARY KEY CLUSTERED
(
[ApprovalTaskID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
USE [CSPMOSSApplication]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_ApprovalTaskStatuses] FOREIGN KEY([Status])
REFERENCES [dbo].[ApprovalTaskStatuses] ([ApprovalTaskStatusID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_ApprovalTaskStatuses]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Organizations] FOREIGN KEY([OrganizationID])
REFERENCES [dbo].[Organizations] ([OrganizationID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Organizations]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Tickets] FOREIGN KEY([TicketID])
REFERENCES [dbo].[Tickets] ([TicketID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Tickets]
GO
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_Users] FOREIGN KEY([ApproverID])
REFERENCES [dbo].[Users] ([UserID])
GO
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_Users]
PK_Approval_Tasks(Clustered)
USE [CSPMOSSApplication]
GO
/****** Object: Index [PK_Approval_Tasks] Script Date: 12/11/2008 12:45:50 ******/
ALTER TABLE [dbo].[ApprovalTasks] ADD CONSTRAINT [PK_Approval_Tasks] PRIMARY KEY CLUSTERED
(
[ApprovalTaskID] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
IX_ApprovalTaskID(Clsutered)
SE [CSPMOSSApplication]
GO
SET ARITHABORT ON
GO
SET CONCAT_NULL_YIELDS_NULL ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GO
SET ANSI_PADDING ON
GO
SET ANSI_WARNINGS ON
GO
SET NUMERIC_ROUNDABORT OFF
GO
/****** Object: Index [IX_ApprovalTaskID] Script Date: 12/11/2008 12:47:27 ******/
CREATE UNIQUE CLUSTERED INDEX [IX_ApprovalTaskID] ON [dbo].[ApprovalsView]
(
[ApprovalTaskID] ASC
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [PRIMARY]
Create View Script
USE [CSPMOSSApplication]
GO
-- =============================================
-- Script Template
-- =============================================
-- [ApprovalTasks]: add columns Link, GlobalApproverID
IF NOT EXISTS(SELECT 1 FROM sysobjects,syscolumns WHERE sysobjects.id = syscolumns.id
AND sysobjects.name = 'ApprovalTasks' AND syscolumns.name = 'Link')
BEGIN
ALTER TABLE ApprovalTasks ADD [Link] [nchar] (255) COLLATE Finnish_Swedish_CI_AS NULL
PRINT 'Column ApprovalTasks.Link was added.'
END
IF NOT EXISTS(SELECT 1 FROM sysobjects,syscolumns WHERE sysobjects.id = syscolumns.id
AND sysobjects.name = 'ApprovalTasks' AND syscolumns.name = 'GlobalApproverID')
BEGIN
ALTER TABLE ApprovalTasks ADD [GlobalApproverID] [int] NULL
PRINT 'Column ApprovalTasks.GlobalApproverID was added.'
ALTER TABLE [dbo].[ApprovalTasks] WITH NOCHECK ADD CONSTRAINT [FK_Approval_Tasks_GlobalApproverID] FOREIGN KEY([GlobalApproverID])
REFERENCES [dbo].[Users] ([UserID])
ALTER TABLE [dbo].[ApprovalTasks] CHECK CONSTRAINT [FK_Approval_Tasks_GlobalApproverID]
END
-- [ApprovalsView]
IF EXISTS (SELECT * FROM sys.fulltext_indexes fti WHERE fti.object_id = OBJECT_ID(N'[dbo].[ApprovalsView]'))
BEGIN
DROP FULLTEXT INDEX ON [dbo].[ApprovalsView]
PRINT 'FULLTEXT INDEX on [ApprovalsView] was dropped.'
END
GO
IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[ApprovalsView]') AND name = N'IX_ApprovalTaskID')
BEGIN
DROP INDEX IX_ApprovalTaskID ON [dbo].[ApprovalsView] WITH ( ONLINE = OFF )
PRINT 'INDEX IX_ApprovalTaskID was dropped.'
END
GO
IF EXISTS (SELECT * FROM sys.views WHERE object_id = OBJECT_ID(N'[dbo].[ApprovalsView]'))
DROP VIEW [dbo].[ApprovalsView]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[ApprovalsView]
WITH SCHEMABINDING
AS
SELECT at.ApprovalTaskID,
at.ApproverID,
at.DueDate,
at.Status,
ats.ApprovalTaskStatusTranslationKey AS StatusText,
at.ApprovedRejectedDate,
at.Reason,
at.OrganizationID,
ord.Name AS OrderName,
ord.TotalPrice,
ord.SubmitDate,
ord.OrdererID,
usr.FirstName AS OrdererFirstName,
usr.LastName AS OrdererLastName,
ordi.Items_Name AS ItemName,
ordi.Items_Description AS ItemDescription,
ordi.OtherInformation AS ItemInformation,
oir.RecipientFullName,
CONVERT(nvarchar(250), oir.DeliveryAddress) As DeliveryAddress,
ti.Description
FROM dbo.ApprovalTasks at
INNER JOIN
dbo.ApprovalTaskStatuses ats ON ats.ApprovalTaskStatusID = at.Status
INNER JOIN
dbo.Orders_Items_Recipients oir ON oir.TicketID = at.TicketID
INNER JOIN
dbo.Orders_Items ordi ON ordi.Orders_ItemsID = oir.Orders_ItemsID
INNER JOIN
dbo.Orders ord ON ordi.OrderID = ord.OrderID
INNER JOIN
dbo.Users usr ON ord.OrdererID = usr.UserID
INNER JOIN
dbo.Tickets ti ON ti.TicketID = at.TicketID
GO
CREATE UNIQUE CLUSTERED INDEX [IX_ApprovalTaskID] ON [dbo].[ApprovalsView]
(
[ApprovalTaskID] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
GO
CREATE FULLTEXT INDEX ON [dbo].[ApprovalsView](
[DeliveryAddress] LANGUAGE [Neutral],
[ItemDescription] LANGUAGE [Neutral],
[ItemInformation] LANGUAGE [Neutral],
[ItemName] LANGUAGE [Neutral],
[OrdererFirstName] LANGUAGE [Neutral],
[OrdererLastName] LANGUAGE [Neutral],
[OrderName] LANGUAGE [Neutral],
[Reason] LANGUAGE [Neutral],
[RecipientFullName] LANGUAGE [Neutral])
KEY INDEX [IX_ApprovalTaskID] ON [ApprovalSearchCatalog]
WITH CHANGE_TRACKING AUTO
GO
ALTER FULLTEXT CATALOG [ApprovalSearchCatalog] rebuild
PRINT 'Catalog [ApprovalSearchCatalog] task to rebuild fulltext index was sent.'
-- STORED PROCEDURES
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ReceiveApprovalTasksFromQueue]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[ReceiveApprovalTasksFromQueue]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Petr Klozik
-- Create date: 19.11.2008
-- Description: Gets approvals which DueDate is over ReferenceDate (now)
-- =============================================
CREATE Procedure [dbo].[ReceiveApprovalTasksFromQueue]
#Limit int
As
BEGIN
SET NOCOUNT ON;
If Not #Limit Is Null Set RowCount #Limit
-- Status: WaitingForApproval = 1
Select Tasks.ApprovalTaskID
From ApprovalTasks Tasks
Where Status = 1 And DueDate < GetDate()
END
'
GO
GRANT EXECUTE ON [dbo].[ReceiveApprovalTasksFromQueue] TO [OMT_IntegrationRole]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[UpdateApprovalTaskInfo]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[UpdateApprovalTaskInfo]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Klozik Petr
-- Create date: 2008-11-25
-- Description: Updates Approval task info to DB
-- =============================================
CREATE PROCEDURE [dbo].[UpdateApprovalTaskInfo]
#ApprovalTaskID int,
#DueDate datetime,
#ApprovalRejectDate datetime,
#Reason nvarchar(1024),
#Status int,
#GlobalApproverID int
AS
BEGIN
SET NOCOUNT ON;
Update ApprovalTasks
Set DueDate = #DueDate,
ApprovedRejectedDate = #ApprovalRejectDate,
Reason = #Reason,
Status = #Status,
GlobalApproverID = #GlobalApproverID
Where ApprovalTaskID = #ApprovalTaskID
END
'
GO
GRANT EXECUTE ON [dbo].[UpdateApprovalTaskInfo] TO [OMT_IntegrationRole]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetUserById]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[GetUserById]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Klozik Petr
-- Create date: 2008-12-04
-- Description: Gets user row by the specified ID.
-- =============================================
CREATE PROCEDURE [dbo].[GetUserById]
(
#UserID int
)
AS
BEGIN
SELECT
UserID,
RTRIM(SID) [SID],
RTRIM(OMTGUID) [OMTGUID],
RTRIM(UserAccount) [UserAccount],
RTRIM(Email) [Email],
RTRIM(FirstName) [FirstName],
RTRIM(LastName) [LastName],
RTRIM(Country) [Country],
RTRIM(City) [City],
RTRIM(PostalNumber) [PostalNumber],
RTRIM(StreetAddress) [StreetAddress],
RTRIM(PhoneNumber) PhoneNumber,
Modified,
Deleted,
Uploaded,
UploadCode,
UploadStatus,
RTRIM(Users.ADUserAccount) AS ADUserAccount
FROM
[dbo].[Users]
WHERE
UserID = #UserID
END
'
GO
GRANT EXECUTE ON [dbo].[GetUserById] TO [OMT_IntegrationRole]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[GetApprovalTaskInfoById]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[GetApprovalTaskInfoById]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
EXEC dbo.sp_executesql #statement = N'
-- =============================================
-- Author: Petr Klozik
-- Create date: 19.11.2008
-- Description: Gets approvals which DueDate is over ReferenceDate (now)
-- =============================================
CREATE Procedure [dbo].[GetApprovalTaskInfoById]
#ApprovalTaskID int
As
BEGIN
SET NOCOUNT ON;
Declare #OrganizationID int
Declare #CurrentApproverID int
Declare #NewApproverID int
Declare #NewOrganizationID int
Select #OrganizationID = OrganizationID, #CurrentApproverID = ApproverID
From ApprovalTasks
Where ApprovalTaskID = #ApprovalTaskID
Set #NewApproverID = (
Select Top 1 o.GlobalApproverID
From Organizations o
Inner Join OrganizationDescendants od On od.OrganizationID = o.OrganizationID
Where od.DescendantID = #OrganizationID
And Not(o.GlobalApproverID Is Null)
Order By o.OrganizationLevel Desc
)
If Not(#NewApproverID Is Null)
Begin
Set #NewOrganizationID = (
Select OrganizationID
from Organizations
Where GlobalApproverID = #NewApproverID)
End
Select Tasks.*, Tickets.Description AS TicketDescription,
Tickets.RequestorID, Tickets.OrdererID,
#NewApproverID AS OrgGlobalApproverID,
#NewOrganizationID AS OrgGlobalApproverOrganizationID
From ApprovalTasks Tasks
inner join Tickets Tickets on Tasks.TicketID = Tickets.TicketID
Where ApprovalTaskID = #ApprovalTaskID
END
'
GO
GRANT EXECUTE ON [dbo].[GetApprovalTaskInfoById] TO [OMT_IntegrationRole]
GO

Lucky guess: any update triggers defined?
2nd lucky guess: ApprovalsView is an indexed view whose index is violated after updating the ApprovalTask table.

look at the definition of the index IX_ApprovalTaskID
Is it possible there is a unique key constraint on ApprovalTaskID, StatusID which would mean there is another row in the table with Status = 2 & ApprovalTaskID = 48
I agree with user Learning, it looks like there's a FOR UPDATE trigger on ApprovalTasks that is inserting an ApprovalTaskID into ApprovalView
Try running DISABLE TRIGGER ALL ON ApprovalTasks and re-run the update

Since the error is coming from the object dbo.ApprovalsView , the problem is with a trigger on ApprovalsTask which is trying to update that table. I really think that ApprovalsView is a table and not a view. But you must have already checked for that.

It looks like a view has been created which is either of, or includes, the table you are updating and that the error occurs when the view is being updated with the changes.
Perhaps the view contains data from different tables which is incompatible, or has stricter constraints set?

Related

The DELETE statement conflicted with the REFERENCE constraint "FK_BlogCommentReply_BlogCommentId"

I have a blog and keeping it simple for discussion, the main tables are Blog, BlogComment, BlogCommentReply and User.
A blog belongs to a User.
A comment belongs to a blog/user.
A comment reply belongs to a blog/comment/user.
I want to delete a User - UserId = 5.
My delete user stored procedure deletes (wrapped in a transaction) in this order:
BlogCommentReply
BlogComment
Blog (if the user is the author of the blog only)
User
It deletes the entry(s) in the BlogCommentReply for the User, then attempts to delete the entry(s) in the BlogComment for the User.
I then get the error:
The DELETE statement conflicted with the REFERENCE constraint "FK_BlogCommentReply_BlogCommentId".
The conflict occurred in database "DBGbngDev", table "dbo.BlogCommentReply", column
'BlogCommentId'.
It still thinks there is an entry in the BlogCommentReply table.
Here is the execute of the stored procedure with debug selects in it to show that it deletes the BlogCommentReply entry but then fails on the delete of the BlogComment.
Table definitions:
----------------------- BlogComment table (parent to blogCommentReply)
CREATE TABLE [dbo].[BlogComment](
[BlogCommentId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[BlogId] [int] NOT NULL,
[BlogCommentContent] [varchar](max) NOT NULL,
[LikeCount] [int] NOT NULL,
[DisLikeCount] [int] NOT NULL,
[DateTimeOfBlogComment] [datetime] NOT NULL,
CONSTRAINT [PK_BlogComment] PRIMARY KEY CLUSTERED
(
[BlogCommentId] 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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[BlogComment] WITH CHECK ADD CONSTRAINT [FK_BlogComment_BlogId] FOREIGN
KEY([BlogId])
REFERENCES [dbo].[Blog] ([BlogId])
GO
ALTER TABLE [dbo].[BlogComment] CHECK CONSTRAINT [FK_BlogComment_BlogId]
GO
ALTER TABLE [dbo].[BlogComment] WITH CHECK ADD CONSTRAINT [FK_BlogComment_UserId] FOREIGN
KEY([UserId])
REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[BlogComment] CHECK CONSTRAINT [FK_BlogComment_UserId]
GO
----------------------- BlogCommentReply table (child)
CREATE TABLE [dbo].[BlogCommentReply](
[BlogCommentReplyId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[BlogCommentId] [int] NOT NULL,
[BlogId] [int] NOT NULL,
[BlogCommentReplyContent] [varchar](max) NOT NULL,
[LikeCount] [int] NOT NULL,
[DisLikeCount] [int] NOT NULL,
[DateTimeOfBlogCommentReply] [datetime] NOT NULL,
CONSTRAINT [PK_BlogCommentReply] PRIMARY KEY CLUSTERED
(
[BlogCommentReplyId] 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
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[BlogCommentReply] WITH CHECK ADD CONSTRAINT [FK_BlogCommentReply_BlogCommentId]
FOREIGN KEY([BlogCommentId])
REFERENCES [dbo].[BlogComment] ([BlogCommentId])
GO
ALTER TABLE [dbo].[BlogCommentReply] CHECK CONSTRAINT [FK_BlogCommentReply_BlogCommentId]
GO
ALTER TABLE [dbo].[BlogCommentReply] WITH CHECK ADD CONSTRAINT [FK_BlogCommentReply_BlogId] FOREIGN
KEY([BlogId])
REFERENCES [dbo].[Blog] ([BlogId])
GO
ALTER TABLE [dbo].[BlogCommentReply] CHECK CONSTRAINT [FK_BlogCommentReply_BlogId]
GO
ALTER TABLE [dbo].[BlogCommentReply] WITH CHECK ADD CONSTRAINT [FK_BlogCommentReply_UserId] FOREIGN
KEY([UserId])
REFERENCES [dbo].[User] ([UserId])
GO
ALTER TABLE [dbo].[BlogCommentReply] CHECK CONSTRAINT [FK_BlogCommentReply_UserId]
GO
Extracted parts of the delete stored procedure (#a_UserId = 5):
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Step 6. Get the number of blog comments replys for the user.
-- Note: there may not be any.
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SELECT #BlogCommentReplysCount = Count(*)
FROM dbo.BlogCommentReply
WHERE ( UserId = #a_UserId )
SELECT #ReturnCode = ##ERROR
IF #ReturnCode <> 0
BEGIN
ROLLBACK TRANSACTION
SELECT #Message = 'Critical Error - procedure DeleteBlog failed during the select of BlogCommentReply. User id: ' + CAST(#a_UserId AS VARCHAR) + '. '
RAISERROR (#Message, 16, 1)
END
SELECT '#BlogCommentReplysCount: ' + CAST(#BlogCommentReplysCount AS VARCHAR) + '. '
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Step 7. Delete the BlogCommentReply entries for the user.
-- Note: the user may not have made any.
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DELETE dbo.BlogCommentReply
WHERE ( UserId = #a_UserId )
SELECT #ReturnCode = ##ERROR,
#RowCount = ##ROWCOUNT
IF #ReturnCode <> 0 AND #RowCount > 0
BEGIN
ROLLBACK TRANSACTION
SELECT #Message = 'Critical Error - procedure DeleteBlog failed during the delete of BlogCommentReply. User id: ' + CAST(#a_UserId AS VARCHAR) + '. '
RAISERROR (#Message, 16, 1)
END
SELECT 'Deleted BlogCommentReply'
SELECT '#ReturnCode: ' + CAST(#ReturnCode AS VARCHAR) + '. '
SELECT '#RowCount: ' + CAST(#RowCount AS VARCHAR) + '. '
SELECT '#a_UserId: ' + CAST(#a_UserId AS VARCHAR) + '. '
SELECT Count(*) as AFTERDELETE
FROM dbo.BlogCommentReply
WHERE ( UserId = #a_UserId )
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Step 8. Get the number of blog comments for this user.
-- Note: there may not be any.
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SELECT #BlogCommentsCount = Count(*)
FROM dbo.BlogComment
WHERE ( UserId = #a_UserId )
SELECT #ReturnCode = ##ERROR
IF #ReturnCode <> 0
BEGIN
ROLLBACK TRANSACTION
SELECT #Message = 'Critical Error - procedure DeleteBlog failed during the select of BlogComment. User id: ' + CAST(#a_UserId AS VARCHAR) + '. '
RAISERROR (#Message, 16, 1)
END
SELECT '#BlogCommentsCount: ' + CAST(#BlogCommentsCount AS VARCHAR) + '. '
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-- Step 9. Delete the BlogComment entries for the user.
-- Note: the user may not have made any.
--+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SELECT Count(*) as BEFORE
FROM dbo.BlogComment
WHERE ( UserId = #a_UserId )
SELECT 'Going to delete BlogComment'
DELETE dbo.BlogComment
WHERE ( UserId = #a_UserId )
SELECT #ReturnCode = ##ERROR,
#RowCount = ##ROWCOUNT
IF #ReturnCode <> 0 AND #RowCount > 0
BEGIN
ROLLBACK TRANSACTION
SELECT #Message = 'Critical Error - procedure DeleteBlog failed during the delete of BlogComment. User id: ' + CAST(#a_UserId AS VARCHAR) + '. '
RAISERROR (#Message, 16, 1)
END
SELECT 'Deleted BlogComment'
I think it's better to have your complete stored procedure script to check the error, but for the mean time I guess the problem is here:
DELETE dbo.BlogCommentReply
WHERE ( UserId = #a_UserId )
Ok, it's deleting all of comment replies which the related user (i.e. #a_UserId = 5) has.
But look at the rest of your script:
DELETE dbo.BlogComment
WHERE ( UserId = #a_UserId )
It's deleting all of user's comments, WHILE they may have some other comment replies for another users and they are not deleted. So I think the problem is here.
Maybe it's better to change the first deletion part to:
DELETE dbo.BlogCommentReply
WHERE ( UserId = #a_UserId )
DELETE dbo.BlogCommentReply
FROM [dbo].[BlogComment]
WHERE dbo.BlogCommentReply.BlogCommentId=[dbo].[BlogComment].BlogCommentId
AND [dbo].[BlogComment].UserId=#a_UserId
It's very simple you are deleting comment's reply of a specific user while other users might have reply under the same comment.
I you really want to delete all related info of a user , you have to go with different approach like finding all replies under that user's comment and delete those.

There are uncommitted transactions / Lock request time out period exceeded

Please assist. I am trying to write a script to change a data type of a column that has dependants in a table. So i decided to combine scripts and start from creating a temp table to move the data away from the proper table so i can drop it and re create it with a new data type for the column in question. The combined scripts executed fine but now they seem to lock other transaction in the database and when i close the script i get the errors in the title. here is my code below...
SET NOCOUNT ON
BEGIN TRY
BEGIN TRAN
PRINT '1.Drop Temporary Table'
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'EmptyDepot.StoreStockTakeTemp')
AND type in (N'U'))
DROP TABLE EmptyDepot.StoreStockTakeTemp
PRINT '====Table Dropped'
PRINT '2.Create Temporary Table'
CREATE TABLE EmptyDepot.StoreStockTakeTemp
(
StoreStockTakeID INT NOT NULL,
CntrNum VARCHAR(11) NOT NULL,
DepotID INT NOT NULL,
StockCaptureDate DATE NOT NULL,
ChUser VARCHAR(50) NOT NULL,
ChDate SMALLDATETIME NOT NULL,
ChStamp TIMESTAMP NOT NULL,
)
PRINT '====Temporary Table Created'
PRINT '3.Populate Temporary Table'
INSERT INTO EmptyDepot.StoreStockTakeTemp
(
StoreStockTakeID,
CntrNum,
DepotID,
StockCaptureDate,
ChUser,
ChDate
)
SELECT StoreStockTakeID,
CntrNum,
DepotID,
StockCaptureDate,
ChUser,
ChDate
FROM EmptyDepot.StoreStockTake
PRINT '====Temporary Table Populated'
PRINT 'Begin Transaction'
PRINT '================='
PRINT '4.Drop Table'
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[EmptyDepot].[PK_StoreStockTakeID]') AND parent_object_id = OBJECT_ID(N'[EmptyDepot].[StoreStockTake]'))
ALTER TABLE [EmptyDepot].[StoreStockTake] DROP CONSTRAINT [PK_StoreStockTakeID]
IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[EmptyDepot].[UX_CntrNum_DepotID]') AND parent_object_id = OBJECT_ID(N'[EmptyDepot].[StoreStockTake]'))
ALTER TABLE [EmptyDepot].[StoreStockTake] DROP CONSTRAINT [UX_CntrNum_DepotID]
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[EmptyDepot].[StoreStockTake]') AND type in (N'U'))
DROP TABLE [EmptyDepot].[StoreStockTake]
PRINT '====Table Dropped'
PRINT '5.Re-Create Table'
SET ANSI_NULLS ON
SET QUOTED_IDENTIFIER ON
SET ANSI_PADDING ON
CREATE TABLE EmptyDepot.StoreStockTake
(
StoreStockTakeID INT NOT NULL,
CntrNum VARCHAR(11) NOT NULL,
DepotID INT NOT NULL,
StockCaptureDate DATE NOT NULL,
ChUser VARCHAR(50) NOT NULL,
ChDate SMALLDATETIME NOT NULL,
ChStamp TIMESTAMP NOT NULL,
CONSTRAINT PK_StoreStockTakeID PRIMARY KEY CLUSTERED
(
StoreStockTakeID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON "PRIMARY"
) ON "PRIMARY"
PRINT '====Table Created'
PRINT '6.Populate Table'
INSERT
INTO EmptyDepot.StoreStockTake
(
StoreStockTakeID,
CntrNum,
DepotID,
StockCaptureDate,
ChUser,
ChDate
)
SELECT StoreStockTakeID,
CntrNum,
DepotID,
StockCaptureDate,
ChUser,
ChDate
FROM EmptyDepot.StoreStockTakeTemp
PRINT '====Table Populated'
COMMIT TRAN
PRINT 'Transaction Committed'
PRINT '====================='
END TRY
BEGIN CATCH
PRINT ERROR_NUMBER()
PRINT ERROR_MESSAGE()
PRINT ERROR_LINE()
ROLLBACK
PRINT 'Transaction Rolled Back'
PRINT '======================='
END CATCH
Script has some problems..
what happens if someone inserts rows while your script is executing?
is it true you don't need constraint (UX_CntrNum_DepotID) in new table?
what about indexes? there could be none thought..
you probably could just rename temp table so you do not need extra insert..
About uncommited transactions- cant see reason, but maybe you started some transaction before executing the command described?

T-SQL get price between two dates

I am making a small database trading system and I have a problem with duplication which I am unsure how to solve. Basically I have a table with prices with the datetime which that price was set and I also have a table with the time a trade was made. I want to get the correct price based on trade datetime.
USE [a_trading_system]
GO
/****** Object: Table [dbo].[Trade] Script Date: 06/30/2012 14:49:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Trade](
[trade_id] [uniqueidentifier] ROWGUIDCOL NOT NULL,
[trade_volume] [int] NOT NULL,
[trade_action] [varchar](5) NOT NULL,
[trade_date] [datetime] NOT NULL,
[timestap] [timestamp] NOT NULL,
[trader_id] [int] NOT NULL,
[exch_ticker] [varchar](8) NOT NULL,
CONSTRAINT [PK_Trades] PRIMARY KEY CLUSTERED
(
[trade_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Trade] WITH CHECK ADD CONSTRAINT [FK_Trade_Contract] FOREIGN KEY([exch_ticker])
REFERENCES [dbo].[Contract] ([exch_ticker])
GO
ALTER TABLE [dbo].[Trade] CHECK CONSTRAINT [FK_Trade_Contract]
GO
ALTER TABLE [dbo].[Trade] WITH CHECK ADD CONSTRAINT [FK_Trade_Trader] FOREIGN KEY([trader_id])
REFERENCES [dbo].[Trader] ([trader_id])
GO
ALTER TABLE [dbo].[Trade] CHECK CONSTRAINT [FK_Trade_Trader]
GO
ALTER TABLE [dbo].[Trade] ADD CONSTRAINT [DF_Trades_trade_id] DEFAULT (newid()) FOR [trade_id]
GO
USE [a_trading_system]
GO
/****** Object: Table [dbo].[Contract] Script Date: 06/30/2012 14:56:19 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Contract](
[exch_ticker] [varchar](8) NOT NULL,
[exch_name] [varchar](50) NULL,
[portfolio_id] [varchar](8) NOT NULL,
[region_cd] [varchar](5) NULL,
CONSTRAINT [PK_Contract] PRIMARY KEY CLUSTERED
(
[exch_ticker] 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].[Contract] WITH CHECK ADD CONSTRAINT [FK_Contract_portfolio] FOREIGN KEY([portfolio_id])
REFERENCES [dbo].[portfolio] ([portfolio_id])
GO
ALTER TABLE [dbo].[Contract] CHECK CONSTRAINT [FK_Contract_portfolio]
GO
ALTER TABLE [dbo].[Contract] WITH CHECK ADD CONSTRAINT [FK_Contract_region] FOREIGN KEY([region_cd])
REFERENCES [dbo].[Region] ([region_cd])
GO
ALTER TABLE [dbo].[Contract] CHECK CONSTRAINT [FK_Contract_region]
GO
USE [a_trading_system]
GO
/****** Object: Table [dbo].[price_details] Script Date: 06/30/2012 14:58:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[price_details](
[price_id] [int] IDENTITY(1,1) NOT NULL,
[exch_ticker] [varchar](8) NOT NULL,
[price_set_date] [datetime] NOT NULL,
[buy_price] [decimal](7, 2) NOT NULL,
[sell_price] [decimal](7, 2) NOT NULL,
CONSTRAINT [PK_price_detail] PRIMARY KEY CLUSTERED
(
[price_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[price_details] WITH CHECK ADD CONSTRAINT [FK_price_details_Contract] FOREIGN KEY([exch_ticker])
REFERENCES [dbo].[Contract] ([exch_ticker])
GO
ALTER TABLE [dbo].[price_details] CHECK CONSTRAINT [FK_price_details_Contract]
GO
View
USE [a_trading_system]
GO
/****** Object: View [dbo].[V_all_uk] Script Date: 06/30/2012 14:39:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER VIEW [dbo].[V_all_uk]
AS
SELECT distinct
co.exch_ticker,
--co.region_cd,
po.portfolio_type,
r.region_name,
r.currency,
t.trade_id,
t.trade_volume,
t.trade_action,
t.trade_date,
pr.buy_price,
--(select distinct pr.buy_price from price_details pr
--where pr.price_set_date <= t.trade_date or pr.price_set_date >= t.trade_date) as price_details,
--MIN(t.trade_date) as trade_date,
--pr.buy_price,
--pr.sell_price,
--pr.price_set_date, --This is the cause of duplication
--pr.price_set_time,case when t.trade_date IS NOT NULL then
--case
--when t.trade_action = 'Buy' then
--t.trade_volume * max(pr.buy_price)
--else
--case when trade_action = 'Sell' then
--t.trade_volume * max(pr.sell_price)
--end
--end as 'trade_value' ,
tr.trader_name,
tr.trader_address,
tr.phone
FROM dbo.Contract as co
INNER JOIN dbo.Portfolio as po ON co.portfolio_id = po.portfolio_id
INNER JOIN dbo.region as r ON co.region_cd = r.region_cd
INNER JOIN dbo.Trade as t ON co.exch_ticker = t.exch_ticker
INNER JOIN dbo.trader as tr ON t.trader_id = tr.trader_id
inner join dbo.price_details as pr on pr.exch_ticker = t.exch_ticker
where r.region_cd = 'UK'
--group by
--co.exch_ticker,
--co.region_cd,
--po.portfolio_type,
--r.region_name,
--r.currency,
--t.trade_id,
--t.trade_volume,
--t.trade_action,
--pr.buy_price,
--pr.sell_price,
--tr.trader_name,
--tr.trader_address,
--tr.phone
GO
These are the three main tables if you need to see data as well just say because I don't usually post SQL questions on this website.
Explanation
If a price is set at 12:20 and the price is 100 then at 12:40 the price is 80. These are two date ranges. So if I buy at 12:30 then I am buying at the price of 100 because that is last price. I am also doing my joins in a view so I can see all data. I will post that now.
Thanks
To get the latest price prior to a particular trade date:
select buy_price, sell_price
from price_details
where exch_ticker = #exch_ticker and price_set_date =
( select max( price_set_date )
from price_details
where exch_ticker = #exch_ticker and price_set_date <= #trade_date )
You may want to add an index on exch_ticker/trade_date(desc) to price_details.
The following assumes SQL Server 2005 or later version.
The idea is first to join Trade and price_details filtering out prices whose times are greater than the corresponding trades' times:
SELECT ...
FROM dbo.Trade t
INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker
The above will get you a row set where every trade has got all prices up to the time of the trade. Now just rank the prices and get the latest one:
WITH trade_prices AS (
SELECT
t.*, -- actually you might want to review the list
pr.price_set_date, -- of columns being pulled from the two tables
pr.buy_price,
pr.sell_price,
rnk = ROW_NUMBER() OVER (PARTITION BY t.trade_id ORDER BY pr.price_set_date DESC)
FROM dbo.Trade t
INNER JOIN dbo.price_details pr ON pr.exch_ticker = t.exch_ticker
)
SELECT *
FROM trade_prices
WHERE rnk = 1
To incorporate this into your view, you will only need to:
1) add the trade_prices CTE,
2) replace two joins, to Trade and to price_details, with a join to trade_prices,
3) add the trade_prices.rnk = 1 condition to the WHERE clause.
Of course, the trader table will now be joined to trade_prices instead of to Trade. And you will also need to change the table aliases pr and t in the view's select list to the one you choose to assign to trade_prices.

How to show the department name in this query?

I have the following database design with repect to the Star schema:
alll table: ID, user_id, cat_id, qa_id
user table: user_id, name, department
category table: cat_id, cat_text, sub_cat_text
QA table: aq_id, q_id, answer_id
question table: q_id, q_text, sub_q_text
answer table: answer_id, text
I have to come up with a query that shows the total number of participants in each question including its subquesiont with all of its answers even if there is no participants in any one of these answers. Fortunately, I could be able to come up with a query that shows: question, sub-question, total number of participants in each answer. However, the problem now is with showing the department. If there is no participants in one of the answer, the department will be shown as NULL. So how to modify this?
My Query:
SELECT dbo.question.q_text, dbo.question.sub_q_text, COUNT(dbo.[user].user_id) AS Expr1, dbo.answer.text, dbo.[user].department
FROM dbo.alll INNER JOIN
dbo.category ON dbo.alll.cat_id = dbo.category.cat_id INNER JOIN
dbo.QA ON dbo.alll.qa_id = dbo.QA.aq_id INNER JOIN
dbo.[user] ON dbo.alll.user_id = dbo.[user].user_id INNER JOIN
dbo.question ON dbo.QA.q_id = dbo.question.q_id RIGHT OUTER JOIN
dbo.answer ON dbo.QA.answer_id = dbo.answer.answer_id
WHERE (dbo.[user].department = 'pmod') AND (dbo.question.q_text = 'q1') OR
(dbo.[user].department IS NULL)
GROUP BY dbo.answer.text, dbo.question.q_text, dbo.question.sub_q_text, dbo.[user].department
Here is the Script of the database:
USE [master]
GO
/****** Object: Database [survey2] Script Date: 05/22/2012 13:18:16 ******/
CREATE DATABASE [survey2] ON PRIMARY
( NAME = N'survey2', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\survey2.mdf' , SIZE = 2048KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'survey2_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQLEXPRESS\MSSQL\DATA\survey2_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [survey2] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [survey2].[dbo].[sp_fulltext_database] #action = 'enable'
end
GO
ALTER DATABASE [survey2] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [survey2] SET ANSI_NULLS OFF
GO
ALTER DATABASE [survey2] SET ANSI_PADDING OFF
GO
ALTER DATABASE [survey2] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [survey2] SET ARITHABORT OFF
GO
ALTER DATABASE [survey2] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [survey2] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [survey2] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [survey2] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [survey2] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [survey2] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [survey2] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [survey2] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [survey2] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [survey2] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [survey2] SET DISABLE_BROKER
GO
ALTER DATABASE [survey2] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [survey2] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [survey2] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [survey2] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [survey2] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [survey2] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [survey2] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [survey2] SET READ_WRITE
GO
ALTER DATABASE [survey2] SET RECOVERY SIMPLE
GO
ALTER DATABASE [survey2] SET MULTI_USER
GO
ALTER DATABASE [survey2] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [survey2] SET DB_CHAINING OFF
GO
USE [survey2]
GO
/****** Object: Table [dbo].[category] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[category](
[cat_id] [int] IDENTITY(1,1) NOT NULL,
[cat_text] [varchar](50) NOT NULL,
[sub_cat_text] [varchar](50) NULL,
CONSTRAINT [PK_category] PRIMARY KEY CLUSTERED
(
[cat_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[answer] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[answer](
[answer_id] [int] IDENTITY(1,1) NOT NULL,
[text] [varchar](50) NOT NULL,
CONSTRAINT [PK_answer] PRIMARY KEY CLUSTERED
(
[answer_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[user] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[user](
[user_id] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[department] [varchar](50) NOT NULL,
CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED
(
[user_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[question] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[question](
[q_id] [int] IDENTITY(1,1) NOT NULL,
[q_text] [varchar](50) NOT NULL,
[sub_q_text] [varchar](50) NULL,
CONSTRAINT [PK_question] PRIMARY KEY CLUSTERED
(
[q_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[QA] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[QA](
[aq_id] [int] IDENTITY(1,1) NOT NULL,
[q_id] [int] NOT NULL,
[answer_id] [int] NOT NULL,
CONSTRAINT [PK_QA] PRIMARY KEY CLUSTERED
(
[aq_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].[alll] Script Date: 05/22/2012 13:18:17 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[alll](
[ID] [int] IDENTITY(1,1) NOT NULL,
[user_id] [int] NULL,
[cat_id] [int] NULL,
[qa_id] [int] NULL,
CONSTRAINT [PK_alll] 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: View [dbo].[showing number of participants in each Q] Script Date: 05/22/2012 13:18:18 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE VIEW [dbo].[showing number of participants in each Q]
AS
SELECT COUNT(dbo.question.q_id) AS Expr1, dbo.[user].department, dbo.category.cat_text, dbo.category.sub_cat_text, dbo.question.q_text
FROM dbo.alll INNER JOIN
dbo.answer ON dbo.alll.answer_id = dbo.answer.answer_id INNER JOIN
dbo.category ON dbo.alll.cat_id = dbo.category.cat_id INNER JOIN
dbo.question ON dbo.alll.q_id = dbo.question.q_id INNER JOIN
dbo.[user] ON dbo.alll.user_id = dbo.[user].user_id
GROUP BY dbo.[user].department, dbo.category.cat_text, dbo.category.sub_cat_text, dbo.question.q_text
GO
EXEC sys.sp_addextendedproperty #name=N'MS_DiagramPane1', #value=N'[0E232FF0-B466-11cf-A24F-00AA00A3EFFF, 1.00]
Begin DesignProperties =
Begin PaneConfigurations =
Begin PaneConfiguration = 0
NumPanes = 4
Configuration = "(H (1[40] 4[20] 2[20] 3) )"
End
Begin PaneConfiguration = 1
NumPanes = 3
Configuration = "(H (1 [50] 4 [25] 3))"
End
Begin PaneConfiguration = 2
NumPanes = 3
Configuration = "(H (1 [50] 2 [25] 3))"
End
Begin PaneConfiguration = 3
NumPanes = 3
Configuration = "(H (4 [30] 2 [40] 3))"
End
Begin PaneConfiguration = 4
NumPanes = 2
Configuration = "(H (1 [56] 3))"
End
Begin PaneConfiguration = 5
NumPanes = 2
Configuration = "(H (2 [66] 3))"
End
Begin PaneConfiguration = 6
NumPanes = 2
Configuration = "(H (4 [50] 3))"
End
Begin PaneConfiguration = 7
NumPanes = 1
Configuration = "(V (3))"
End
Begin PaneConfiguration = 8
NumPanes = 3
Configuration = "(H (1[56] 4[18] 2) )"
End
Begin PaneConfiguration = 9
NumPanes = 2
Configuration = "(H (1 [75] 4))"
End
Begin PaneConfiguration = 10
NumPanes = 2
Configuration = "(H (1[66] 2) )"
End
Begin PaneConfiguration = 11
NumPanes = 2
Configuration = "(H (4 [60] 2))"
End
Begin PaneConfiguration = 12
NumPanes = 1
Configuration = "(H (1) )"
End
Begin PaneConfiguration = 13
NumPanes = 1
Configuration = "(V (4))"
End
Begin PaneConfiguration = 14
NumPanes = 1
Configuration = "(V (2))"
End
ActivePaneConfig = 0
End
Begin DiagramPane =
Begin Origin =
Top = 0
Left = 0
End
Begin Tables =
Begin Table = "alll"
Begin Extent =
Top = 61
Left = 226
Bottom = 178
Right = 386
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "answer"
Begin Extent =
Top = 182
Left = 0
Bottom = 269
Right = 160
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "category"
Begin Extent =
Top = 36
Left = 426
Bottom = 138
Right = 586
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "question"
Begin Extent =
Top = 189
Left = 427
Bottom = 291
Right = 587
End
DisplayFlags = 280
TopColumn = 0
End
Begin Table = "user"
Begin Extent =
Top = 45
Left = 0
Bottom = 147
Right = 160
End
DisplayFlags = 280
TopColumn = 0
End
End
End
Begin SQLPane =
End
Begin DataPane =
Begin ParameterDefaults = ""
End
Begin ColumnWidths = 9
Width = 284
Width = 2265
Width = 1500
Width = 1500
Width = 1500
Width = 1500
Width = 1500
Width = 1500
Width = 1500
End
End
Begin CriteriaPane =
Begin ColumnWidths = 12
Column = 1440
Alias = 900
Table' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'VIEW',#level1name=N'showing number of participants in each Q'
GO
EXEC sys.sp_addextendedproperty #name=N'MS_DiagramPane2', #value=N' = 1170
Output = 720
Append = 1400
NewValue = 1170
SortType = 1350
SortOrder = 1410
GroupBy = 1350
Filter = 1350
Or = 1350
Or = 1350
Or = 1350
End
End
End
' , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'VIEW',#level1name=N'showing number of participants in each Q'
GO
EXEC sys.sp_addextendedproperty #name=N'MS_DiagramPaneCount', #value=2 , #level0type=N'SCHEMA',#level0name=N'dbo', #level1type=N'VIEW',#level1name=N'showing number of participants in each Q'
GO
/****** Object: ForeignKey [FK_QA_answer] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[QA] WITH CHECK ADD CONSTRAINT [FK_QA_answer] FOREIGN KEY([answer_id])
REFERENCES [dbo].[answer] ([answer_id])
GO
ALTER TABLE [dbo].[QA] CHECK CONSTRAINT [FK_QA_answer]
GO
/****** Object: ForeignKey [FK_QA_question] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[QA] WITH CHECK ADD CONSTRAINT [FK_QA_question] FOREIGN KEY([q_id])
REFERENCES [dbo].[question] ([q_id])
GO
ALTER TABLE [dbo].[QA] CHECK CONSTRAINT [FK_QA_question]
GO
/****** Object: ForeignKey [FK_alll_category] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[alll] WITH CHECK ADD CONSTRAINT [FK_alll_category] FOREIGN KEY([cat_id])
REFERENCES [dbo].[category] ([cat_id])
GO
ALTER TABLE [dbo].[alll] CHECK CONSTRAINT [FK_alll_category]
GO
/****** Object: ForeignKey [FK_alll_QA] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[alll] WITH CHECK ADD CONSTRAINT [FK_alll_QA] FOREIGN KEY([qa_id])
REFERENCES [dbo].[QA] ([aq_id])
GO
ALTER TABLE [dbo].[alll] CHECK CONSTRAINT [FK_alll_QA]
GO
/****** Object: ForeignKey [FK_alll_user] Script Date: 05/22/2012 13:18:17 ******/
ALTER TABLE [dbo].[alll] WITH CHECK ADD CONSTRAINT [FK_alll_user] FOREIGN KEY([user_id])
REFERENCES [dbo].[user] ([user_id])
GO
ALTER TABLE [dbo].[alll] CHECK CONSTRAINT [FK_alll_user]
GO
This is a query I think you are looking for. It first cross-joins users and questions. Now that there are all possible combinations between the two you may start counting matching answers.
EDIT: changed join to answer to cross join to be able to count 0s.
SELECT
dbo.[user].department,
dbo.question.q_text,
dbo.question.sub_q_text,
dbo.answer.text,
COUNT(qa.answer_id) AS Users_Answered
FROM [user]
CROSS JOIN question
CROSS JOIN answer
LEFT JOIN alll
ON [user].User_ID = alll.User_ID
LEFT JOIN qa
ON alll.qa_id = qa.aq_id
AND question.q_id = qa.q_id
AND qa.answer_id = answer.answer_id
GROUP BY
dbo.[user].department,
dbo.question.q_text,
dbo.question.sub_q_text,
dbo.answer.text
ORDER BY 1, 2
You might check it # Sql Fiddle.
New version of query # Sql Fiddle.

Long running INSERT query on SQL Server 2005

I have been sniffing out forums and blogs lately, but need some help with a long running query. It's part of a system of stored procedures. This specified statement used to run in about 5 minutes, but lately has been running up to 72 hours!
Here's the setup:
SQL Server 2005 with 28GB memory. Two mountpoints to a SAN with shared disks consisting of 10 spindles. Data is on one mountpoint, Log on another, tempdb on data space. Just one userdatabase on this server.
Here's two tables, condit and condmod. Condit contains 800K records, condmod is initially empty. I issue a truncate mcmain.condmod before the process starts, for testing purposes.
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__condit__con_notm__000AF8CF]') AND type = 'D')
BEGIN
ALTER TABLE [mcmain].[condit] DROP CONSTRAINT [DF__condit__con_notm__000AF8CF]
END
GO
/****** Object: Table [mcmain].[condit] Script Date: 02/07/2012 11:57:47 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[mcmain].[condit]') AND type in (N'U'))
DROP TABLE [mcmain].[condit]
GO
/****** Object: Table [mcmain].[condit] Script Date: 02/07/2012 11:57:49 ******/
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[mcmain].[condit]') AND type in (N'U'))
BEGIN
CREATE TABLE [mcmain].[condit](
[con_levgln] [char](13) NULL,
[con_stat] [char](4) NULL,
[con_dscgrp] [char](35) NULL,
[con_levart] [char](20) NULL,
[con_desc] [char](50) NULL,
[con_disc1] [numeric](5, 0) NULL,
[con_disc2] [numeric](5, 0) NULL,
[con_disc3] [numeric](5, 0) NULL,
[con_ntprce] [numeric](9, 0) NULL,
[con_dtstrt] [datetime] NULL,
[con_dtend] [datetime] NULL,
[con_volc] [char](8) NULL,
[con_updnmr] [char](20) NULL,
[con_notmod] [bit] NULL,
[con_ascver] [char](5) NULL,
[con_prddat] [datetime] NULL,
[con_cusgln] [char](13) NULL,
[con_cusdeb] [char](40) NULL,
[con_rowid] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__condit__con_notm__000AF8CF]') AND type = 'D')
BEGIN
ALTER TABLE [mcmain].[condit] ADD DEFAULT ((0)) FOR [con_notmod]
END
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__condmod__com_not__7E22B05D]') AND type = 'D')
BEGIN
ALTER TABLE [mcmain].[condmod] DROP CONSTRAINT [DF__condmod__com_not__7E22B05D]
END
GO
/****** Object: Table [mcmain].[condmod] Script Date: 02/07/2012 11:57:56 ******/
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[mcmain].[condmod]') AND type in (N'U'))
DROP TABLE [mcmain].[condmod]
GO
/****** Object: Table [mcmain].[condmod] Script Date: 02/07/2012 11:57:58 ******/
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[mcmain].[condmod]') AND type in (N'U'))
BEGIN
CREATE TABLE [mcmain].[condmod](
[com_levgln] [char](13) NULL,
[com_stat] [char](4) NULL,
[com_dscgrp] [char](35) NULL,
[com_levart] [char](20) NULL,
[com_desc] [char](50) NULL,
[com_disc1] [numeric](5, 0) NULL,
[com_disc2] [numeric](5, 0) NULL,
[com_disc3] [numeric](5, 0) NULL,
[com_ntprce] [numeric](9, 0) NULL,
[com_dtstrt] [datetime] NULL,
[com_dtend] [datetime] NULL,
[com_volc] [char](8) NULL,
[com_updnmr] [char](20) NULL,
[com_notmod] [bit] NULL,
[com_ascver] [char](8) NULL,
[com_prddat] [datetime] NULL,
[com_cusgln] [char](13) NULL,
[com_cusdeb] [char](40) NULL,
[com_rowid] [int] IDENTITY(1,1) NOT NULL
) ON [PRIMARY]
END
GO
IF NOT EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DF__condmod__com_not__7E22B05D]') AND type = 'D')
BEGIN
ALTER TABLE [mcmain].[condmod] ADD DEFAULT ((0)) FOR [com_notmod]
END
GO
Here's the isolated code that runs a long time:
DECLARE #TempIdTable TABLE ([com_rowid] Int PRIMARY KEY)
INSERT #TempIdTable([com_rowid])
SELECT cmd.[com_rowid]
FROM [mcmain].[condmod] AS cmd
LEFT OUTER JOIN [mcmain].[condit] AS cdt
ON con_levgln = com_levgln
AND IsNull(con_dscgrp,'') = IsNull(com_dscgrp,'')
AND IsNull(con_levart,'') = IsNull(com_levart,'')
AND IsNull(con_volc,'') = IsNull(com_volc,'')
AND IsNull(con_cusgln,'') = IsNull(com_cusgln,'')
AND IsNull(con_cusdeb,'') = IsNull(com_cusdeb,'')
WHERE con_levgln is NULL
--select * from #TempIdTable
INSERT INTO mcmain.condit(con_levgln
,con_stat
,con_dscgrp
,con_levart
,con_desc
,con_disc1
,con_disc2
,con_disc3
,con_ntprce
,con_dtstrt
,con_dtend
,con_volc
,con_notmod
,con_updnmr
,con_ascver
,con_cusgln
,con_cusdeb)
SELECT com_levgln
,com_stat
,com_dscgrp
,com_levart
,com_desc
,com_disc1
,com_disc2
,com_disc3
,com_ntprce
,com_dtstrt
,com_dtend
,com_volc
,com_notmod
,com_updnmr
,com_ascver
,com_cusgln
,com_cusdeb
FROM [mcmain].[condmod] AS cmd
INNER JOIN #TempIdTable AS tit
ON tit.com_rowid = cmd.com_rowid
The insert into the #TempIdTable takes forever. What can I do to speed up this process?
TIA
Cees Cappelle
p.s. I have clustered indexes on both tables, like:
/****** Object: Index [condmodTest] Script Date: 02/07/2012 13:24:34 ******/
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[mcmain].[condmod]') AND name = N'condmodTest')
CREATE CLUSTERED INDEX [condmodTest] ON [mcmain].[condmod]
(
[com_levgln] ASC,
[com_dscgrp] ASC,
[com_levart] ASC,
[com_volc] ASC,
[com_cusgln] ASC,
[com_cusdeb] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
If I do a straight select (just now), it takes 2 seconds.
Here's the code:
SELECT com_levgln
,com_stat
,com_dscgrp
,com_levart
,com_desc
,com_disc1
,com_disc2
,com_disc3
,com_ntprce
,com_dtstrt
,com_dtend
,com_volc
,com_notmod
,com_updnmr
,com_ascver
,com_cusgln
,com_cusdeb
FROM mcmain.condmod
LEFT OUTER JOIN mcmain.condit
ON con_levgln = com_levgln
AND IsNull(con_dscgrp,'') = IsNull(com_dscgrp,'')
AND IsNull(con_levart,'') = IsNull(com_levart,'')
AND IsNull(con_volc,'') = IsNull(com_volc,'')
AND IsNull(con_cusgln,'') = IsNull(com_cusgln,'')
AND IsNull(con_cusdeb,'') = IsNull(com_cusdeb,'')
WHERE con_levgln is NULL
I just did a Actial Execution plan with the following code. It took 3'16'' ???
truncate table mcmain.condit
CREATE TABLE #TempIdTable ([com_rowid] Int PRIMARY KEY)
-- DECLARE #TempIdTable TABLE
-- ([com_rowid] Int PRIMARY KEY)
INSERT #TempIdTable
([com_rowid])
SELECT cmd.[com_rowid]
FROM [mcmain].[condmod] AS cmd
LEFT OUTER JOIN [mcmain].[condit] AS cdt
ON con_levgln = com_levgln
AND IsNull(con_dscgrp,'') = IsNull(com_dscgrp,'')
AND IsNull(con_levart,'') = IsNull(com_levart,'')
AND IsNull(con_volc,'') = IsNull(com_volc,'')
AND IsNull(con_cusgln,'') = IsNull(com_cusgln,'')
AND IsNull(con_cusdeb,'') = IsNull(com_cusdeb,'')
WHERE con_levgln is NULL
-- AND com_updnmr = #plannummer
INSERT INTO mcmain.condit
(con_levgln
,con_stat
,con_dscgrp
,con_levart
,con_desc
,con_disc1
,con_disc2
,con_disc3
,con_ntprce
,con_dtstrt
,con_dtend
,con_volc
,con_notmod
,con_updnmr
,con_ascver
,con_cusgln
,con_cusdeb)
SELECT com_levgln
,com_stat
,com_dscgrp
,com_levart
,com_desc
,com_disc1
,com_disc2
,com_disc3
,com_ntprce
,com_dtstrt
,com_dtend
,com_volc
,com_notmod
,com_updnmr
,com_ascver
,com_cusgln
,com_cusdeb
FROM [mcmain].[condmod] AS cmd
INNER JOIN #TempIdTable AS tit
ON tit.com_rowid = cmd.com_rowid
Same statement but using a tablevariable took 1'39''
When I run the sp, the same statement takes hours and hours. Still don't get it.
If the SELECT itself takes a long time
You could consider using NOT EXISTS rather than OUTER JOIN ... NULL as this is often more efficient.
Also I would get rid of the non sargable ISNULL comparisons.
SELECT cmd.[com_rowid]
FROM [mcmain].[condmod] AS cmd
WHERE NOT EXISTS (SELECT *
FROM [mcmain].[condit] AS cdt
WHERE con_levgln = com_levgln
AND EXISTS (SELECT con_dscgrp,
con_levart,
con_volc,
con_cusgln,
con_cusdeb
INTERSECT
SELECT com_dscgrp,
com_levart,
com_volc,
com_cusgln,
com_cusdeb))
If the SELECT runs quite quickly on its own but just not when inserting to the table variable then check whether in the quick case you get a parallel plan.
Queries that insert to table variables do not get parallelised so if that is the issue you could consider changing to a #temp table.
If neither of these suggestions help then I suggest you start monitoring the wait types when this procedure runs. See the paper "SQL Server 2005 Waits and Queues"
Note: the use of #tables uses tempdb.
You should try increasing the number of temp db files... you can start with the number of tempdb files equal to the number of procs you have... but as a good starting point just jump to 10... The problem you could be having is contention for tempdb files. You should look for page latching in tempdb.
This article discusses how the generalization I wrote above is a misconception (but not necessarily wrong) but in doing so does a good job of explaining the issue. It also points you to other articles which give informatoin on how to look for page latching.
A SQL Server DBA myth a day: (12/30) tempdb should always have one data file per processor core