gb2*_*b2d 6 t-sql sql-server database-design
我需要删除并重新创建一个表,该表用于"缓存"昂贵的视图.视图可能会更改,我希望尽可能简化维护,因此我希望新表能够反映最新版本的视图.
我还希望能够防止读取错误,如果一个过程在被删除和重新创建的过程中尝试访问该表.我正在使用一个事务,但是我不确定它是否会在一个'drop'表上工作,因为它不存在.
我在运行drop/recreate视图时,在循环中从视图中完成了一个基本测试,30 x SELECT.到目前为止没有错误.
我已经考虑过使用insert进行截断/删除,但是将来视图中可能更改的列要求我保持尽可能灵活,并且固定列不会对此有所帮助.
任何人都可以告诉我,如果事务在被删除时保护表不受读取访问,这是安全的,还是有更好的方法?
删除/重新创建代码:
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
Run Code Online (Sandbox Code Playgroud)
更新:修改查询跟随Brads答案:
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
Run Code Online (Sandbox Code Playgroud)
我使用了我来配音丢弃触发器的过程.我在创建表需要一些时间时非常成功地使用了这个过程,并且我不希望在重建过程中所有需要该表的应用程序/用户都被占用.
<TableName>_New)DROP TABLE <TableName>)EXEC sql_rename...)[REF]我通常用这个逻辑创建一个存储过程并在一个作业中安排它.
*注意:要充分利用此过程,您需要在步骤1和步骤2之间在新表上创建所需的任何索引.这意味着您还必须预先修复它们并将其重命名与表一起使用以避免在脚本再次运行时遇到问题.
为了增加安全性,您可以围绕步骤2和3创建事务.设置隔离级别Serialized将使其最安全,但我没有经验,如果它实际上将防止错误.没有使用交易,我从未遇到过任何问题.