Ian*_*oyd -1 sql-server synonym sql-server-2008-r2
几十年来我一直用VIEW
s作为同义词:
CREATE VIEW dbo.Banks AS
SELECT *
FROM OtherDatabase.dbo.Banks
Run Code Online (Sandbox Code Playgroud)
我这样做,所以我可以抽象"真正的"表格.当它发生变化时,就像改变视图一样简单:
这很好用.它不会导致优化器出现任何问题,并且我能够根据需要编辑视图.
从SQL Server 2005开始,Microsoft引入了同义词:
CREATE SYNONYM dbo.Banks FOR OtherDatabase.dbo.Banks
Run Code Online (Sandbox Code Playgroud)
它似乎工作相同的VIEW
方式.我看过的每个执行计划都表现得相同.
不幸的是,似乎同义词无法提供我们需要的基本功能之一:
提供一个抽象层,用于保护客户端应用程序免受对基础对象的名称或位置所做的更改
您无法更改同义词指向的位置.因为没有ALTER SYNONYM语句,所以首先必须删除同义词,然后重新创建具有相同名称的同义词,但将同义词指向新位置.
实际上,这不会发生.我永远不会这样做.我不会使用一种机制,要求我从数据库中删除对象以更改设置.我当然不是要删除所有容易改变的观点,与替换它们的同义词,而且还得给大家讲解为什么使一切困难是"更好".
所以我的问题是,使用视图我有什么损失吗?
我缺少的表或视图同义词是否有美德?
除了必须打电话
RefreshAllViews
以防万一我忘记了我在某个地方换了一张桌子
我甚至不使用存储过程的同义词:
CREATE PROCEDURE dbo.GetUSDNoonRateAsOf @tradeDate datetime AS
EXECUTE OtherDatabase.dbo.GetUSDNoonRateAsOf @tradeDate
Run Code Online (Sandbox Code Playgroud)
我失踪的同义词中是否有值?
我们在每个数据库中都有一个标准程序.重新排序或插入列会对视图造成严重破坏; 所以他们必须"刷新".
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
Run Code Online (Sandbox Code Playgroud)
天知道为什么SQL Server不会为我做这件事.
同义词是一种更加透明的重定向.我更喜欢它们而不是视图,因为需要维护视图.当你SELECT *
特别使用时.
我不确定我是否认为缺乏ALTER SYNONYM
真正的阻挡者.同义词的删除/创建是一个非常简单的元数据操作,并且速度非常快.省略错误处理以简化:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
DROP SYNONYM ...
CREATE SYNONYM ...
COMMIT TRANSACTION;
Run Code Online (Sandbox Code Playgroud)
同样,对于存储过程,如果基本存储过程接口发生更改(例如,添加参数),则还必须更改包装程序 - 而不是使用同义词.
一个缺点是你可以在视图上创建一个而不是触发器,但你不能在同义词上创建.您还无法通过同义词(主要是DDL)执行其他操作.当然,IntelliSense可能无法正常运行,具体取决于版本.
无法记住语法似乎是一个伪造的借口给我.没有花哨的选择或条款 ; 只是同义词的两部分名称,以及它所引用的对象的2部分,3部分或4部分名称:
CREATE SYNONYM dbo.Something FOR Server.Database.dbo.SomethingElse;
Run Code Online (Sandbox Code Playgroud)
如果你不能记住它,你是如何创建同义词的?
我还建议彻底简化您的存储过程(并防止它在dbo
架构中没有任何视图时失败,或者该过程由默认架构与视图架构不同的人执行,或者视图具有'
或其名称中的空格,或以其他方式违反标识符的任何规则(您可以在此页面上找到它们)):
CREATE PROCEDURE [dbo].[RefreshAllViews]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql NVARCHAR(MAX) = N'';
SELECT @sql += '
EXEC sp_refreshview ' + CHAR(39)
+ QUOTENAME(REPLACE(s.name,'''',''''''))
+ '.' + QUOTENAME(REPLACE(v.name,'''','''''')) + CHAR(39) + ';'
FROM sys.views AS v
INNER JOIN sys.schemas AS s
ON v.[schema_id] = s.[schema_id];
PRINT @sql;
EXEC sp_executesql @sql;
END
GO
Run Code Online (Sandbox Code Playgroud)
至少,如果您要保留光标,请停止使用可怕的默认选项(将光标声明为LOCAL FAST_FORWARD
),然后使用sys.views
而不是INFORMATION_SCHEMA
.
天知道为什么SQL Server不会为我做这件事.
因为SQL Server是软件,并且它并不完美 - 特别是涉及到依赖项时.主要问题是您SELECT *
首先在视图中使用了违反最佳做法的行为.耸耸肩如果您接受关于同义词的挂钩,您将不必担心这一点.
归档时间: |
|
查看次数: |
2094 次 |
最近记录: |