我正在做一些T-SQL編程,並在我的數據庫中定義了一些視圖。數據模型現在仍在改變,我定義了一些表函數。有時我故意用刷新用戶函數的元數據t-SQL
select * from MYVIEW
在這樣的表函數中返回所有的列。如果視圖更改(或表)該函數崩潰,我需要重新編譯它。我知道這是一般的好東西,所以它可以防止地獄裏的錯誤,但仍然...
有沒有一種方法來寫這樣的功能,所以不要在我每次改變基礎表上的東西時炸開我的臉?或者,也許我做的東西完全錯誤的...
感謝您的幫助
我正在做一些T-SQL編程,並在我的數據庫中定義了一些視圖。數據模型現在仍在改變,我定義了一些表函數。有時我故意用刷新用戶函數的元數據t-SQL
select * from MYVIEW
在這樣的表函數中返回所有的列。如果視圖更改(或表)該函數崩潰,我需要重新編譯它。我知道這是一般的好東西,所以它可以防止地獄裏的錯誤,但仍然...
有沒有一種方法來寫這樣的功能,所以不要在我每次改變基礎表上的東西時炸開我的臉?或者,也許我做的東西完全錯誤的...
感謝您的幫助
定義意見「WITH SCHEMABINDING」
我會參考你在這裏我的回答涵蓋類似的東西...
「select * from table」 vs 「select colA,colB,etc from table」 interesting behaviour in SqlServer2005
在這種情況下,這個問題是不是UDF,但意見的行爲,而不SCHEMABINDING
編輯:Cade Roux的sp_refreshsqlmodule可能會訣竅。我從來沒有用過它。
gbn's answer是最好的 - 但是當您有SCHEMABINDING時,這通常會阻止您在不首先刪除SCHEMABINDING的情況下進行基礎更改,然後在重新創建模塊時將其替換。如果對象引用數據庫外的對象,則不能使用SCHEMABINDING。
如果這個難度如此之大,您不希望或不能使用SCHEMABINDING,然後在某些常規過程中使用sp_refreshsqlmodule,您可以在實際使用它們之前運行它來檢查SQL模塊是否存在錯誤(它可以在任何非模式綁定視圖,UDF,存儲過程等等上運行)都是你的朋友。
您可以同時使用這兩種技術 - 您不能(也不需要)針對schemabound對象運行sp_refreshsqlmodule。
例如,你只能在這些模塊運行:
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE (
OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)), N'IsSchemaBound') IS NULL
OR OBJECTPROPERTY(OBJECT_ID(QUOTENAME(ROUTINE_SCHEMA) + '.' + QUOTENAME(ROUTINE_NAME)),
N'IsSchemaBound') = 0
)
我不知道這是因爲我只使用SCHEMABINDING。有用。 – gbn 2010-03-16 14:08:48
@gbn - 我可以的時候使用SCHEMABINDING,但是它不能跨數據庫使用(並且是正確的),它只能在其他架構綁定對象之上工作 - 如果鏈中的任何對象都不能被綁定,則使用SCHEMABINDING在那裏結束。在這種情況下,可以使用sp_refreshsqlmodule充分監視打破外部更改,然後才能真正分解任何內容。sp_refreshsqlmodule將導致擴展屬性在SQL Server 2005中的表值UDF上丟失(但是,當您改變它們以移除並重新添加SCHEMABINDING時,就會發生這種情況)。 – 2010-03-16 14:34:05
我不相信,這達到他的目的。他想要用select *來改變視圖中使用的表。 從MSDN讀取以下內容 SCHEMABINDING [...]此外,如果這些語句影響視圖定義,那麼參與具有模式綁定的視圖的表上的ALTER TABLE語句將失敗。 我認爲這正是luckyluke不想要的行爲。 – 2010-03-16 13:59:13
@doug_w:hobson的選擇:使用WITH SCHEMABINDING或每次運行sp_refreshview。沒有選擇。你也可以在我引用同一鏈接的地方閱讀我的其他答案。僅供參考,我在我所有的觀點和udfs中使用SCHEMABINDING。 – gbn 2010-03-16 14:02:12