1

我写了这两个函数:

USE muziekdatabase
GO
CREATE FUNCTION fnSpecNivAantal
    (
        @Niveau as char(1)
    )

RETURNS char(1)
AS 

BEGIN

    DECLARE @Aantal AS int

    IF @Niveau = 'A'
    SET @Aantal = (SELECT COUNT(*) FROM STUK WHERE niveaucode = 'A')

    ELSE IF @Niveau = 'B' 
    SET @Aantal = (SELECT COUNT(*) FROM STUK WHERE niveaucode = 'B')

    ELSE IF @Niveau = 'C'
    SET @Aantal = (SELECT COUNT(*) FROM STUK WHERE niveaucode = 'C')

RETURN @Aantal

END

USE muziekdatabase
GO

ALTER FUNCTION fnHoogsteNummer 
    (
        @EersteNummer as numeric,
        @TweedeNummer as numeric
    )
RETURNS numeric 
AS 
BEGIN

    DECLARE @HoogsteNummer as VARCHAR(MAX)

    IF MAX(@Eerstenummer) > MAX(@TweedeNummer)
    SET @HoogsteNummer = @EersteNummer
    ELSE IF
    MAX(@Tweedenummer) > MAX(@Eerstenummer)
    SET @HoogsteNummer = @TweedeNummer
    ELSE IF
    @EersteNummer = @TweedeNummer
    SET @HoogsteNummer = 'Nummers zijn gelijk' 
    ELSE
    SET @HoogsteNummer = 'Er is iets fout gegaan'

    RETURN @HoogsteNummer
END

现在他们几乎可以正常工作了。但有一件事不太对劲。当我在函数中插入一个值时,结果是一个具有相同答案的整个列表。就像 10 行只有 3,它应该只有 1 行,数字 3。我知道我可以使用DISTINCT,但我认为该功能有问题。我尝试使用CASE / WHEN,但这也不起作用..

4

2 回答 2

1
CREATE FUNCTION fnSpecNivAantal
(
 @Niveau as char(1)
)
RETURNS INT  --<-- since you are returning count use INT variable not char
AS 
BEGIN

    DECLARE @Aantal AS int; 

    IF (@Niveau IN ('A' , 'B', 'C'))
     BEGIN
       SELECT @Aantal = COUNT(*) 
       FROM STUK WHERE niveaucode = @Niveau
     END

RETURN @Aantal

END

抱歉,您的第二个功能无法理解。

于 2017-12-04T13:43:01.770 回答
0

将这些函数更改为内联表值函数将提供一些性能优势。它们在考虑功能方面略有不同,但值得付出努力。您需要养成的一个习惯是定义变量和参数的大小和精度。不要偷懒,不要做数字之类的事情。您应该精确并定义大小。SQL Server 不会自动调整小数位数和精度以满足它找到的值。相反,它使用可能适合或不适合您的数据的默认大小。

您的第一个功能可以大大简化为此。

CREATE FUNCTION fnSpecNivAantal
(
    @Niveau as char(1)
)RETURNS TABLE AS RETURN

    SELECT Niveau = COUNT(*) 
    FROM STUK 
    WHERE niveaucode = @Niveau
        AND niveaucode IN ('A', 'B', 'C')

第二个有点不同。您将函数定义为返回数字(无比例或精度),但您的代码可以返回数字或字符串文字。这不起作用,因为函数的所有部分都必须返回相同的数据类型。没什么大不了的,您只需意识到您的返回数据类型在这里是 varchar 而不是数字。该函数可以像这样转换为内联表值函数。

ALTER FUNCTION fnHoogsteNummer 
    (
        @EersteNummer as numeric, --need to define scale and precision
        @TweedeNummer as numeric --need to define scale and precision
    )
RETURNS TABLE AS RETURN

    SELECT CASE WHEN @Eerstenummer > @TweedeNummer THEN convert(varchar(25), @EersteNummer)
            WHEN @TweedeNummer > @EersteNummer THEN convert(varchar(25), @TweedeNummer)
            WHEN @TweedeNummer = @EersteNummer THEN 'Nummers zijn gelijk' 
            ELSE 'Er is iets fout gegaan'
            END

请注意,这两个函数都是一个语句。这就是使它们成为内联表值函数的原因。如果您开始定义变量并有多个语句,它将成为一个多语句表值函数,并且性能可能比标量函数更差。

于 2017-12-04T14:54:04.070 回答