Мне нужно отбросить и воссоздать таблицу, которая существует для «кеширования» дорогостоящего представления. Представление может измениться, и я хочу максимально упростить обслуживание, поэтому я хочу, чтобы новая таблица отражала последнюю версию представления.
Я также хочу иметь возможность предотвратить ошибки чтения, если процедура пытается получить доступ к таблице, когда она находится в процессе удаления и воссоздания. Я использую транзакцию, но не уверен, сработает ли она с «отброшенной» таблицей за ту долю секунды, которой она не существует.
Я провел базовый тест, 30 x SELECT из просмотр в цикле при запуске представления перетаскивания / воссоздания. Пока ошибок нет.
Я рассматривал усечение / удаление со вставкой, но потенциально изменяющиеся столбцы в представлении в будущем требуют, чтобы я сохранял это как можно более гибким, и фиксированные столбцы не помогут с этим.
Может ли кто-нибудь сказать мне, защитит ли транзакция таблицу от доступа для чтения при удалении и это безопасно, или если есть лучший способ?
Удалить / восстановить код:
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
ОБНОВЛЕНИЕ: измененный запрос после ответа Брэдса:
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