2010-03-16 35 views
0

我正在做一些T-SQL編程,並在我的數據庫中定義了一些視圖。數據模型現在仍在改變,我定義了一些表函數。有時我故意用刷新用戶函數的元數據t-SQL

select * from MYVIEW 

在這樣的表函數中返回所有的列。如果視圖更改(或表)該函數崩潰,我需要重新編譯它。我知道這是一般的好東西,所以它可以防止地獄裏的錯誤,但仍然...

有沒有一種方法來寫這樣的功能,所以不要在我每次改變基礎表上的東西時炸開我的臉?或者,也許我做的東西完全錯誤的...

感謝您的幫助

回答

2

定義意見「WITH SCHEMABINDING」

我會參考你在這裏我的回答涵蓋類似的東西...

「select * from table」 vs 「select colA,colB,etc from table」 interesting behaviour in SqlServer2005

在這種情況下,這個問題是不是UDF,但意見的行爲,而不SCHEMABINDING

編輯:Cade Roux的sp_refreshsqlmodule可能會訣竅。我從來沒有用過它。

+0

我不相信,這達到他的目的。他想要用select *來改變視圖中使用的表。 從MSDN讀取以下內容 SCHEMABINDING [...]此外,如果這些語句影響視圖定義,那麼參與具有模式綁定的視圖的表上的ALTER TABLE語句將失敗。 我認爲這正是luckyluke不想要的行爲。 – 2010-03-16 13:59:13

+0

@doug_w:hobson的選擇:使用WITH SCHEMABINDING或每次運行sp_refreshview。沒有選擇。你也可以在我引用同一鏈接的地方閱讀我的其他答案。僅供參考,我在我所有的觀點和udfs中使用SCHEMABINDING。 – gbn 2010-03-16 14:02:12

3

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 
       ) 
+0

我不知道這是因爲我只使用SCHEMABINDING。有用。 – gbn 2010-03-16 14:08:48

+0

@gbn - 我可以的時候使用SCHEMABINDING,但是它不能跨數據庫使用(並且是正確的),它只能在其他架構綁定對象之上工作 - 如果鏈中的任何對象都不能被綁定,則使用SCHEMABINDING在那裏結束。在這種情況下,可以使用sp_refreshsqlmodule充分監視打破外部更改,然後才能真正分解任何內容。sp_refreshsqlmodule將導致擴展屬性在SQL Server 2005中的表值UDF上丟失(但是,當您改變它們以移除並重新添加SCHEMABINDING時,就會發生這種情況)。 – 2010-03-16 14:34:05