SQLでは、ユーザー定義関数(User Defined Functions, UDF)を介してビジネスロジックを実装でき、計算やビジネスルールの一部をデータベースに移行することができます。
スカラー関数は単一の値を返し、式の中で呼び出されます。たとえば、パラメータに基づいて合計を計算する場合:
CREATE FUNCTION dbo.GetDiscount(@price DECIMAL(10,2), @loyaltyLevel INT) RETURNS DECIMAL(10,2) AS BEGIN RETURN @price * CASE WHEN @loyaltyLevel = 1 THEN 0.95 WHEN @loyaltyLevel = 2 THEN 0.90 ELSE 1.0 END END; -- 使用例: SELECT Name, dbo.GetDiscount(Price, LoyaltyLevel) AS DiscountPrice FROM Products;
テーブル関数は行のセット(テーブル)を返します:
CREATE FUNCTION dbo.ActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- 使用: SELECT * FROM dbo.ActiveOrders(123);
違い、制限、推奨事項:
INLINEテーブル関数とマルチステートメントテーブル関数の違いは何ですか?この選択はパフォーマンスにどのように影響しますか?
回答と例:
-- INLINE CREATE FUNCTION dbo.InlineActiveOrders(@userId INT) RETURNS TABLE AS RETURN ( SELECT * FROM Orders WHERE UserId = @userId AND Status = 'Active' ); -- マルチステートメント CREATE FUNCTION dbo.MultiActiveOrders(@userId INT) RETURNS @result TABLE (...) AS BEGIN INSERT INTO @result SELECT ... -- ロジック RETURN END
歴史
プロジェクト: 財務分析。
多くのテーブルに対するレポートクエリのSELECT部分でスカラーUDFを使用しました: SELECT Amount, dbo.CalcTax(Amount, Type) FROM Transactions。クエリはUDFの行ごとの処理のために5-10分かかりました。組み込みのCASEに書き直したところ、時間が数秒に短縮されました。
歴史
プロジェクト: Eコマース。 ユーザーのショッピングカートを検索するために、複数の段階のフィルタリングロジックを持つマルチステートメントテーブル関数を使用しました。SQLが最適なプランを構築せず、必要な要素でさえスキャンを実行していました。INLINE関数に置き換えたところ、クエリの速度が50倍向上しました。
歴史
プロジェクト: CRM。 ボーナス計算のビジネスロジックを複雑なUDFに移行しました。数か月後、ビジネスの計算式が変更され、データとの厳密な結びつきのために関数の更新が難しいことが判明しました。反復的な製品ではUDFがバックエンドとDB間の変更協調に高いコストをもたらしました。