向表中添加列会更改视图的sql

时间:2012-04-26 07:31:46

标签: sql view

在向视图所依赖的表中添加列时,我对具有命名字段的视图产生了意想不到的影响。

SQL:

SELECT     dbo.AccessCustomFieldDepartment.AccessCustomFieldDepartmentID, dbo.AccessCustomFieldDepartment.AccessCustomField_StoreID, 
                      dbo.AccessCustomFieldDepartment.AccessCustomField_ShopOwner, dbo.AccessCustomFieldDepartment.AccessCustomField_CVRnumber, 
                      dbo.AccessCustomFieldDepartment.AccessCustomField_OpenMonToWed, dbo.AccessCustomFieldDepartment.AccessCustomField_OpenMonToThu, 
                      dbo.AccessCustomFieldDepartment.AccessCustomField_OpenMonToFri, dbo.AccessCustomFieldDepartment.AccessCustomField_OpenMonToTue,
--..
--a bunch of other fields
--..

                  dbo.AccessUser.AccessUserAddress, dbo.AccessUser.AccessUserAddress2, dbo.AccessUser.AccessUserZip, dbo.AccessUser.AccessUserCity, 
                  dbo.AccessUser.AccessUserCountry, dbo.AccessUser.AccessUserWeb
FROM         dbo.AccessUser INNER JOIN
                      dbo.AccessCustomFieldDepartment ON dbo.AccessUser.AccessUserID = dbo.AccessCustomFieldDepartment.AccessCustomFieldDepartmentID

当其他人员代码对表AccessUser动态添加列时,服务器或其他东西会更改视图的sql!

EG:

dbo.AccessUser.AccessUserCountry, dbo.AccessUser.AccessUserWeb

变为

dbo.AccessUser.AccessUserCountry AS AccessUserCity, 
dbo.AccessUser.AccessUserWeb AS AccessUserCountry

这大大F * * *我的数据显示......就像View试图保持各列的位置一样。

删除列会神奇地将sql更改回原始版本。

所以问题是:

  • 发生了什么事?是服务器吗? CMS中的一些功能 软件(添加字段功能的地方)
  • 我可以在视图上进行设置,使其认为sql语句是100%静态的吗?

此致

斯蒂恩

1 个答案:

答案 0 :(得分:1)

要重新编译视图或过程,请执行以下命令:

/* View: */
exec sp_refreshview 'dbo.MyViewName'

/* Procedure, FN, IF, TF */
exec sp_recompile 'dbo.ProcedureName'
exec sp_recompile 'dbo.ScalarFunctionName'
exec sp_recompile 'dbo.InlineFunctionName'
exec sp_recompile 'dbo.TableFunctionName'

您可以从sysobjects获取对象列表。将它们选择到表变量中应该相对容易,并生成一个循环,依次重新编译每个变量。

set nocount on
declare @o table(
    id int primary key,
    object_full_name nvarchar(1000),
    xtype nvarchar(20)
)
insert @o
select
    id, object_schema_name(id) + '.' + object_name(id) as object_full_name, xtype
from sysobjects so 
where 
    xtype in ('V', 'P', 'FN', 'TF', 'IF')


while exists (select 1 from @o)
begin
    declare @id int
    declare @object_full_name nvarchar(1000)
    declare @xtype nvarchar(20)
    set @id = null
    select top 1 @id = id, @object_full_name = object_full_name, @xtype = xtype from @o order by xtype, object_full_name, id
    delete @o where id = @id
    if @xtype = 'V'
    begin
        raiserror('Marking for recompile - %s: %s', 0, 1, @xtype, @object_full_name)
        exec dbo.sp_refreshview @object_full_name
    end
    else
    begin
        raiserror('Marking for recompile - %s: %s', 0, 1, @xtype, @object_full_name)
        exec dbo.sp_recompile @object_full_name
    end
end

您也可以考虑使用DDL触发器按需执行此操作。