Hi,
I need to drop and recreate a table, which exists to "cache" an expensive view. The view may change and I want to make maintenance as easy as possible, so I want the new table to reflect the latest version of the view.
I also want to be able to prevent read errors should a procedure try to access the table while it is in the middle of being dropped and recreated. I'm using a transaction, but I'm not sure if that will work on a 'dropped' table for that split second that it doesn't exists.
I've done a basic test, 30 x SELECT's from the view in a loop while running the drop / recreate view. No errors so far.
I have considered a Truncate / Delete with insert, but the potentially changing columns on the view in the future require that I keep this as flexible as possible, and fixed columns wont help with this.
Can anyone tell me if the transaction will protect the table from read access while being dropped and this is safe, or if there is a better way?
Drop / Recreate Code:
BEGIN TRAN
BEGIN TRY
DROP TABLE Persisted_View_1
SELECT * INTO Persisted_View_1
FROM View_1
END TRY
BEGIN CATCH
RAISERROR('The procedure proc_PersistView1 failed to commit, the transaction was rolled back', 16, 1)
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
END CATCH
IF @@TRANCOUNT > 0
BEGIN
COMMIT TRAN
END
GO
UPDATE: Revised query following Brads Answer:
ALTER PROCEDURE proc_Drop_Recreate_Persisted_View_MyData
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRAN
BEGIN TRY
-- Re create
SELECT * INTO Persisted_View_MyData_Temp FROM View_MyData
-- Create index on product ID
CREATE CLUSTERED INDEX [IX_ProductID_ProductTypeID] ON [dbo].[Persisted_View_MyData_Temp]
(
[productID] ASC,
[productTypeID] 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]
-- Check and drop table
IF EXISTS ( SELECT Id FROM sysObjects WHERE Name like 'Persisted_View_MyData' )
BEGIN
DROP TABLE Persisted_View_MyData
END
EXEC sp_rename 'Persisted_View_MyData_Temp', 'Persisted_View_MyData'
END TRY
BEGIN CATCH
RAISERROR('The procedure proc_PersistViewMyData failed to commit, the transaction was rolled back', 16, 1)
IF @@TRANCOUNT > 0
BEGIN
ROLLBACK TRAN
END
END CATCH
IF @@TRANCOUNT > 0
BEGIN
COMMIT TRAN
END
END