1

スコアをintとして返す関数があります

CREATE FUNCTION [dbo].[CalculateScore]
   (@gender CHAR(1), @name varchar(20), @dob datetime, 
   @weight int, @height int, @smoker BIT, @Earning int)   
RETURNS INT
AS
BEGIN
DECLARE @Score INT


DECLARE @Age INT
SELECT @Age = DATEDIFF(YEAR, @dob, GETDATE())

SELECT 
    @Score = CASE 
                WHEN @Age BETWEEN 20 AND 30 THEN 5
                WHEN @Age BETWEEN 31 AND 40 THEN 4
                WHEN @Age BETWEEN 41 AND 50 THEN 3
                WHEN @Age > 50 THEN 2
                ELSE 0
            END


DECLARE @WeightHeight INT

SET @WeightHeight = @Weight / @height

SET 
   @Score = @Score + 
            CASE 

              WHEN @WeightHeight BETWEEN 20 AND 25 THEN 1
              WHEN @WeightHeight BETWEEN 25 AND 30 THEN 3
              WHEN @WeightHeight BETWEEN 30 AND 35 THEN 5
              WHEN @WeightHeight BETWEEN 35 AND 40 THEN 2
              ELSE 0  
            END


IF @Smoker = 0
    SET @Score = @Score + 5


SET 
   @Score = @Score + 
            CASE 
               WHEN @Earning < 50000 THEN 1
               WHEN @Earning BETWEEN 50001 AND 60000 THEN 2
               WHEN @Earning BETWEEN 60001 AND 70000 THEN 3
               WHEN @Earning > 70000 THEN 4
            END


RETURN @Score
END

次のようなINSERTコードを実行できるようにしたい

INSERT INTO Table
(Gender, Name, dob, Weight, Height, Smoker, Earning)
VALUES 
(1, 'James', '19841230', 59, 185, 0, 80000), 
(1, 'Jack', '19700430', 75, 182, 1, 95000),
(1, 'James', '19670721', 60, 167, 0, 75000); 
GO

のようなものではなく

INSERT INTO Table(Gender, Name, dob, Weight, Height, Smoker, Earning, memberID, CalculatedScore)
SELECT
@Gender, @Name, @dob, @Weight, @Height, @Smoker, @Earning
dbo.CalculateScore(@Gender, @Name, @dob, @Weight, @Height, @Smoker, @Earning)

これらの値をテーブルに挿入しますが、関数から計算されたスコアと一意の主キーを、テーブルにもある「CalculatedScore」列と「Member_ID」列に自動的に追加します。

挿入の前に関数を呼び出して戻り値を保存することになっていると思いますが、その方法がわかりません。

どんな助けでも大歓迎です!

乾杯

4

3 に答える 3

3

計算列を追加できますか?

ALTER TABLE Member ADD CalculatedScore AS 
  dbo.CalculateScore(Gender, Name, dob, Weight, Height, Smoker, Earning);

ただし、この列は決定論的ではないため、インデックスを作成することはできません。つまり、データを実際に変更しなくても (つまり、1 年経ったために) スコアが変化する可能性があるため、トリガーを使用してこれを正確に維持することさえできません。インデックス付けできる永続化された列が必要な場合、唯一の方法は、静的列を更新する夜間ジョブを実行することです。

SQL Fiddle の例

于 2013-09-09T07:54:37.700 に答える
1

あなたの機能を少し単純化しました -

CREATE FUNCTION [dbo].[CalculateScore] 
(
      @dob DATETIME
    , @weight INT
    , @height INT
    , @smoker BIT
    , @Earning INT
)
RETURNS INT
AS BEGIN

    DECLARE @Score INT

    SELECT @Score =
        CASE
            WHEN Age BETWEEN 20 AND 30 THEN 5
            WHEN Age BETWEEN 31 AND 40 THEN 4
            WHEN Age BETWEEN 41 AND 50 THEN 3
            WHEN Age > 50 THEN 2 
            ELSE 0
        END +
        CASE
            WHEN WeightHeight BETWEEN 20 AND 25 THEN 1
            WHEN WeightHeight BETWEEN 25 AND 30 THEN 3
            WHEN WeightHeight BETWEEN 30 AND 35 THEN 5
            WHEN WeightHeight BETWEEN 35 AND 40 THEN 2 
            ELSE 0
        END +
        CASE
            WHEN @Smoker = 0 THEN 5 ELSE 0
        END +
        CASE
            WHEN @Earning < 50000 THEN 1
            WHEN @Earning BETWEEN 50001 AND 60000 THEN 2
            WHEN @Earning BETWEEN 60001 AND 70000 THEN 3
            WHEN @Earning > 70000 THEN 4
            ELSE 0
        END
    FROM
    (
        SELECT  Age = DATEDIFF(YEAR, @dob, GETDATE())
            ,   WeightHeight = CAST(@Weight / @height AS INT)
    ) t

    RETURN @Score

END
于 2013-09-09T07:36:13.323 に答える
0

挿入前に呼び出すことができるトリガーを使用してみてください

于 2013-09-09T07:28:18.477 に答える