2

ビューが依存するテーブルに列を追加すると、名前付きフィールドを持つビューで非常に予期しない影響があります。

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を変更します!

例えば:

dbo.AccessUser.AccessUserCountry, dbo.AccessUser.AccessUserWeb

に変更されます

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

これは、結果として得られるデータのプレゼンテーションを大幅に改善します....ビューがそれぞれの列の位置を維持しようとするのと同じです。

列を削除すると、魔法のようにSQLが元に戻ります。

質問は次のとおりです。

  • 何が起こっている?サーバーですか?CMS ソフトウェアの一部の機能 (フィールドの追加機能がある場所)
  • ビューを設定して、SQL ステートメントを 100% 静的にすることはできますか?

よろしく、

スティーン

4

1 に答える 1

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トリガーを検討することもできます。

于 2012-04-27T11:36:18.080 に答える