几十年来,我一直使用VIEW
s 作为同义词:
CREATE VIEW dbo.Banks AS
SELECT *
FROM OtherDatabase.dbo.Banks
我这样做是为了抽象出“真实”表的位置。当它改变时,就像改变视图一样简单:
这很好用。它不会导致优化器出现任何问题,并且我已经能够根据需要编辑视图。
同义词
从 SQL Server 2005 开始,Microsoft 引入了同义词:
CREATE SYNONYM dbo.Banks FOR OtherDatabase.dbo.Banks
它似乎与该方法相同VIEW
。我看过的每个执行计划的行为都是一样的。
不幸的是,同义词似乎无法提供它们的基本功能之一,即我需要的功能:
提供一个抽象层,保护客户端应用程序免受对基础对象的名称或位置的更改
您无法更改同义词指向的位置。因为没有 ALTER SYNONYM 语句,您首先必须删除同义词,然后重新创建具有相同名称的同义词,但将同义词指向新位置。
他们有什么可赎回的品质吗?
实际上,这不会发生。我永远不会这样做。我不会使用要求我从数据库中删除对象以更改设置的机制。我当然不会删除所有容易更改的VIEW,用 SYNONYM替换它们,并且必须向大家解释为什么让一切变得更难是“更好”。
所以我的问题是,使用视图有什么损失吗?
- 每个执行计划看起来都与同义词相同
- 我可以随时轻松更改“查看同义词”
我缺少的表或视图同义词有什么优点吗?
除了必须打电话
RefreshAllViews
以防我忘记我在某处换了桌子
甚至存储过程
我什至不使用存储过程的同义词:
CREATE PROCEDURE dbo.GetUSDNoonRateAsOf @tradeDate datetime AS
EXECUTE OtherDatabase.dbo.GetUSDNoonRateAsOf @tradeDate
我缺少的同义词有什么价值吗?
更新: RefreshAllViews 程序
我们在每个数据库中都有一个标准程序。重新排序或插入列会对视图造成严重破坏;所以他们必须“刷新”。
CREATE PROCEDURE [dbo].[RefreshAllViews] AS
-- This sp will refresh all views in the catalog.
-- It enumerates all views, and runs sp_refreshview for each of them
SET NOCOUNT ON
DECLARE abc CURSOR FOR
SELECT TABLE_NAME AS ViewName
FROM INFORMATION_SCHEMA.VIEWS
ORDER BY newid()
OPEN abc
DECLARE @ViewName varchar(128)
--DECLARE @ParmDefinition NVARCHAR(500)
-- Build select string once
DECLARE @SQLString nvarchar(2048)
--SET @SQLString = N'EXECUTE sp_RefreshView @View'
--SET @ParmDefinition = N'@View nvarchar(128)'
FETCH NEXT FROM abc
INTO @ViewName
WHILE @@FETCH_STATUS = 0
BEGIN
IF @ViewName <> 'IndexServerNodes'
BEGIN
SET @SQLString = 'EXECUTE sp_RefreshView '+@ViewName
PRINT @SQLString
EXECUTE sp_ExecuteSQL @SQLString--, @ParmDefinition, @View = @ViewName
END
FETCH NEXT FROM abc
INTO @ViewName
END
CLOSE abc
DEALLOCATE abc
天知道为什么 SQL Server 不为我做这件事。