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);

但是,您将无法索引此列,因为它不是确定性的。也就是说,分数可能会在数据没有实际变化的情况下发生变化(即因为它们已经大了一岁),因此您甚至无法使用触发器准确地保持这一点。如果您想要一个可以被索引的持久列,唯一的方法是运行一个更新静态列的夜间作业。

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 回答