4 Stimmen

Benötige Hilfe bei skalarwertiger Funktion in SQL Server 2008

Ich brauche Hilfe bei dieser skalarwertigen Funktion.

Ich möchte den Wert, den ich in MaxValue erhalte, in der Zeile max(Value) AS MaxValue .

Die Abfrage funktioniert und gibt nur 1 Wert zurück, wenn ItemId et ListPropertyId existiert, aber ich bin nicht in der Lage, eine Funktion davon zu erstellen.

CREATE FUNCTION GetLpivMax 
(
    -- Add the parameters for the function here
    @ItemId int,
    @ListPropertyId int
)
RETURNS int
AS
BEGIN
  DECLARE @output INT;
  WITH U AS (
    SELECT i.Id AS ItemId,
           lpiv.Value,
           lp.Id AS ListPropertyId
      FROM ListPropertyItemValues lpiv
      JOIN ListPropertyItems lpi ON lpi lpi.Id = lpiv.ListPropertyItemId 
      JOIN ListProperties lp ON lp.Id = lpi.ListPropertyId
      JOIN Items i ON i.Id = lpiv.ItemId)
    SELECT @output = MAX(u.value)
      FROM U u
     WHERE u.listpropertyid = @ListPropertyId 
       AND u.itemid = @ItemId
  GROUP BY u.listpropertyid, u.itemid

  RETURN @output
END
GO

3voto

Rob Farley Punkte 15180

Ich habe Ihre Frage hochgestuft, aber mir gefällt keine der Antworten. Sie sollten Ihren Code stattdessen in eine Inline-Funktion mit Tabellenwert ändern. Dieser Code wird jedes Mal als prozedural betrachtet, und es ist nur eine einzige Abfrage.

Ich schrieb darüber unter http://msmvps.com/blogs/robfarley/archive/2009/12/05/dangers-of-begin-and-end.aspx aber ich werde Ihnen kurz erklären, was Sie tun sollten:

CREATE FUNCTION GetLpivMax  
( 
    -- Add the parameters for the function here 
    @ItemId int, 
    @ListPropertyId int 
) 
RETURNS TABLE AS 
RETURN (
SELECT MAX(lpiv.Value) as LpivMax
    FROM ListPropertyItemValues lpiv 
    JOIN ListPropertyItems lpi ON lpi.Id = lpiv.ListPropertyItemId  
    JOIN ListProperties lp ON lp.Id = lpi.ListPropertyId 
    JOIN Items i ON i.Id = lpiv.ItemId 
   WHERE lp.id = @ListPropertyId  
     AND i.id = @ItemId 
GROUP BY lp.id, i.id 
);

Benutzen Sie es nun so:

SELECT ip.*, m.LpivMax
FROM ItemsAndProperties ip
CROSS APPLY
dbo.GetLpivMax(ip.ItemID, ip.ListPropertyID) m
;

Sie können OUTER APPLY verwenden, wenn Sie keine Zeilen aus Ihrem Datensatz eliminieren wollen. Sie können zusätzliche Aggregate hinzufügen, die vollständig ignoriert werden, wenn Sie sich nicht auf sie beziehen. Vor allem aber wird der Query Optimizer Ihre Abfrage vereinfachen, d. h. wenn er einen großen Teil der Arbeit vermeiden kann, wird er es tun.

Ich hoffe, das hilft...

2voto

OMG Ponies Punkte 312816

Verwendung:

DECLARE @output INT

BEGIN
  WITH U AS (
    SELECT i.Id AS ItemId,
           lpiv.Value,
           lp.Id AS ListPropertyId
      FROM ListPropertyItemValues lpiv
      JOIN ListPropertyItems lpi ON lpi.Id = lpiv.ListPropertyItemId 
      JOIN ListProperties lp ON lp.Id = lpi.ListPropertyId
      JOIN Items i ON i.Id = lpiv.ItemId)
    SELECT @output = MAX(u.value)
      FROM U u
     WHERE u.listpropertyid = @ListPropertyId 
       AND u.itemid = @ItemId
  GROUP BY u.listpropertyid, u.itemid

  RETURN @output
END

のことです。 SELECT @output = MAX(u.value) ordnet den Wert dem @output Variable, dann müssen Sie sie mit der RETURN Syntax. Eine Alternative wäre die Angabe eines Out-Parameters, je nach Bedarf.

Ich habe auch Ihre JOIN-Syntax von ANSI-89 nach ANSI-99 konvertiert. Die Leistung ist gleichwertig, aber LEFT JOINs werden besser unterstützt als die ältere Syntax. Außerdem wird die Syntax von anderen Datenbanken weitgehend unterstützt (was sie bei Bedarf portabel macht).

Versuchen Sie es auch:

  SELECT @output = MAX(lpiv.Value)
    FROM ListPropertyItemValues lpiv
    JOIN ListPropertyItems lpi ON lpi.Id = lpiv.ListPropertyItemId 
    JOIN ListProperties lp ON lp.Id = lpi.ListPropertyId
    JOIN Items i ON i.Id = lpiv.ItemId
   WHERE lp.id = @ListPropertyId 
     AND i.id = @ItemId
GROUP BY lp.id, i.id

Ich glaube nicht, dass Sie das CTE brauchen...

0voto

Gabriel McAdams Punkte 54162

Fügen Sie diese Zeilen in Ihren Code ein und es sollte funktionieren:

Fügen Sie Folgendes am Anfang ein (direkt nach BEGIN)

DECLARE @output int

Fügen Sie dies am Ende hinzu (kurz vor END)

RETURN @output

Fassen Sie das Ganze so zusammen:

CREATE FUNCTION GetLpivMax 
(
    -- Add the parameters for the function here
    @ItemId int,
    @ListPropertyId int
)
RETURNS int
AS
BEGIN

  DECLARE @output INT;

  WITH U AS (
    SELECT i.Id AS ItemId,
           lpiv.Value,
           lp.Id AS ListPropertyId
      FROM ListPropertyItemValues lpiv
      JOIN ListPropertyItems lpi ON lpi lpi.Id = lpiv.ListPropertyItemId 
      JOIN ListProperties lp ON lp.Id = lpi.ListPropertyId
      JOIN Items i ON i.Id = lpiv.ItemId)

    SELECT @output = MAX(u.value)
      FROM U u
     WHERE u.listpropertyid = @ListPropertyId 
       AND u.itemid = @ItemId
  GROUP BY u.listpropertyid, u.itemid

  RETURN @output
END
GO

0voto

SCALAR VALUED FUNCTION EXAMPLE BY RAJESH

CREATE FUNCTION GETMYDATE(@YEAR INT)
RETURNS DATETIME 
AS
BEGIN
    DECLARE @DATE DATETIME
    IF @YEAR>2000
        SET @DATE=GETDATE()
    ELSE
        SET @DATE=NULL

    RETURN @DATE
END

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X