SQL Server 2008之用戶自定義函數


  1. 標量函數,當使用T-SQL實現時不能返回rowversioncursortable,當使用托管代碼實現時,不能返回rowversioncursortabletextntextimage
  1. 創建標量函數時,CREATE FUNCTION必須是批處理中唯一語句;和存儲過程不同,使用函數時,必須使用BEGIN...END抱住函數體,存儲過程中BEGIN...END是可選的
  1. 創建用戶自定以的標量函數的Guidelines
  • 函數使用兩部分命名法,函數中引用的數據庫對象也使用兩部分命名法
  • 在函數中,錯誤將導致整個函數停止執行,而存儲過程或者觸發器則是只取消產生錯誤的語句執行,然后繼續執行接下來的語句
  1. 函數修改底層數據庫被認為是有副作用的,在SQL Server中函數不允許有副作用,即不允許修改底層數據庫,因此你可能無法修改數據庫中的數據,無法執行存儲過程,無法執行動態SQL(能不能執行主要看是否修改了底層數據庫)
  1. 函數分為Deterministic,即在相同的數據庫狀態下提供同樣的輸入總是返回相同的值和Non-deterministic,即返回不同的值,可以使用OBJECTPROPERTY()函數確定函數是不是deterministic
  1. 表值函數通常和參數化視圖是等價的,但是視圖是不允許傳遞用戶自定義的參數的;對於內聯函數來說,不用將函數體包含在BEGIN...END語句塊中,返回類型為TABLE,返回的表結構從SELECT語句進行推導
  1. 多語句表值函數允許更加復雜的返回表構建邏輯,函數體必須包含在BEGIN...END語句中,必須提供返回表的定義
  1. 視圖代碼直接納入到查詢代碼中(也就是將定義視圖的代碼和查詢代碼組合成一個查詢的代碼,而不是先執行視圖查詢,再對返回數據執行查詢),而標量函數則不是這樣的;在SELECT列表和WHERE語句中使用標量函數將帶來嚴重的性能問題
  1. 內聯表值函數將直接將代碼納入使用他們的查詢中,而多語句表值函數則不會這么做,除非多語句表值函數在查詢中只執行一次,否則其性能會很差;CROSS APPLY操作符用來為左邊表中每一行執行表值函數,這會帶來嚴重的性能問題,盡量避免
  1. 上述兩點中指出的性能問題,都是逐行調用了自定義函數,這樣需要為每行去提取自定義函數的定義,然后去執行這些定義,導致了性能問題;更深層次的原因是因為函數采用了過程式的處理方法,而SQL Server查詢數據則是基於數據集合的,這樣在采用過程式的逐行處理時,SQL Server性能就會顯著降低
  1. 創建函數的指導原則:
  • 決定使用的函數類型
  • 為每個任務創建一個函數,避免創建大函數,完成多任務的函數
  • 使用兩部分命名法
  • 考慮使用函數時的性能影響,通常來說,內聯函數比多語句函數性能要好
  • 考慮和索引組合使用時的影響,對索引列使用函數很可能移除索引列的應用
  • 避免引發錯誤,在函數中不允許錯誤處理
  1. 表值函數和存儲過程都能實現相似的結果,一些應用程序只能使用表值函數,另外一些只能使用存儲過程
    1. 函數
    • 返回結果更容易訪問,存儲過程得使用輸出參數,使用起來更復雜
    • 可以將表數據返回給一個變量
    • 不能有數據相關的副作用,即不能修改數據,不能自行動態SQL語句
    • 多語句表值函數通常有性能問題
    1. 存儲過程
    • 可以修改數據
    • 可以執行動態語句
    • 可以包含詳細的異常處理
    • 可以返回多結果集
  1. 表值函數和視圖通常都可以實現相似的結果
    1. 視圖
    • 能夠被幾乎所有應用程序使用
    • 和表非常相似
    • 可以被更新
    • 可以使用INSTEAD OF觸發器
    1. 表值函數
    • 類似於參數化視圖
    • 通常導致嚴重的性能問題(多語句表值函數)
    • 不能納入到使用的查詢中
    • 只有內聯表值函數可以更新


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM