0

Kann ich eine Funktion aufrufen, die nicht aus einer Stored Procedure definiert ist?Aufruf einer Funktion von Stored Procedure

Betrachten wir eine gespeicherte Prozedur, die so aussieht:

CREATE PROCEDURE [dbo].[stp__getClients] 
AS 

BEGIN 
    SET NOCOUNT ON; 


    Select Id,Name,Status , 
      (CASE WHEN Status = 3 then run_date_calc(FromDate , ToDate) else '' 
      end) as DateRangeDesc 
    From ClientsTbl 

... 
END 
GO 

ich eine andere Eigenschaft auf die Select wie das hinzufügen möchten:

innerhalb der
(CASE WHEN Status = 3 then run_date_calc(FromDate , ToDate) else '' end) 

Wir wollen schaffen eine Funktion SP genannt run_date_calc, dass wird zwei Daten erhalten und eine Zeichenfolge mit seiner Bereich Beschreibung sieht wie folgt zurück:

declare @d1 datetime, @d2 datetime, @year int, @month int, @d int 
set @d1 = '2009-09-24' 
set @d2 = '2012-04-23' 

set @year = datediff(year, @d1, @d2) - 1 
set @month = datediff(month, dateadd(year, @year, @d1), @d2) 
if dateadd(month, @month, dateadd(year, @year, @d1)) > @d2 set @month = @month - 1 

set @d = datediff(day, dateadd(month, @month, dateadd(year, @year, @d1)), @d2) 
print cast(@year as nvarchar) + ' year(s) ' + cast(@month as nvarchar) + ' month(s) and ' + cast(@d as nvarchar) + ' day(s)' 

Ist es möglich, eine "Inside-Funktion" zu erstellen und sie innerhalb des SP zu verwenden, ohne sie in der DB zu erstellen?

Dank

Antwort

1

Sie können nicht „schaffen“ oder eine Funktion innerhalb einer SP definieren, Nr. Sie müssen es in der/a-Datenbank erstellen und dann auf das von Ihnen erstellte Objekt verweisen.

Wenn aus irgendeinem ungerade Grund Sie nicht wollen, das Objekt zu bleiben, können Sie es in TempDB CREATE könnte, sie verwenden und dann DROP es (aber dies würde die SP kann nicht bedeuten, die von zwei Benutzern ausgeführt werden, gleichzeitig , da das Objekt bereits existiert).

Erstellen Sie es einfach dauerhaft.

1

eine Funktion in der Datenbank wie folgt erstellen ...

CREATE FUNCTION dbo.run_date_calc 
(
    @d1 datetime 
, @d2 datetime 
) 
RETURNS VARCHAR(100) 
AS 
BEGIN 

    Declare @year int, @month int, @d int; 

    SET @year = datediff(year, @d1, @d2) - 1 
    SET @month = datediff(month, dateadd(year, @year, @d1), @d2) 

    IF dateadd(month, @month, dateadd(year, @year, @d1)) > @d2 set @month = @month - 1 

    set @d = datediff(day, dateadd(month, @month, dateadd(year, @year, @d1)), @d2) 

    RETURN ( cast(@year as varchar(10)) + ' year(s) ' 
      + cast(@month as varchar(10)) + ' month(s) and ' 
      + cast(@d  as varchar(10)) + ' day(s)' 
      ) 

END 
GO 

Und dann rufen Sie einfach an, wenn aus Ihrem proc

CREATE PROCEDURE [dbo].[stp__getClients] 
AS 

BEGIN 
    SET NOCOUNT ON; 


    Select Id,Name,Status , 
      (CASE WHEN Status = 3 then dbo.run_date_calc(FromDate , ToDate) else '' 
      end) as DateRangeDesc 
    From ClientsTbl 

... 
END 
GO 
+0

Danke, aber Sie beantworten meine Frage nicht. Ich habe das schon gemacht, ich suche nach einer Möglichkeit, es inline zu machen, ohne eine andere Funktion zu definieren. – ron

1

Wie Sie informiert wurden, können Sie in einer Funktion nicht definieren können, ein SP. Außerdem ist Ihre Funktion falsch. bei meiner Lösung suchen:

declare @d1 datetime, @d2 datetime, @year int, @month int, @d int 
set @d1 = '2009-09-24' 
set @d2 = '2012-04-23' 


SET @year = NULLIF(DATEDIFF(year, @d1, @d2), 0) 

IF @year IS NOT NULL AND DATEADD(year, @year, @d1) > @d2 
    SET @year = NULLIF(@year - 1, 0) 

SET @month = NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(@year, 0), @d1), @d2), 0) 

IF DATEADD(month, ISNULL(@month, 0), DATEADD(year, ISNULL(@year, 0), @d1)) > @d2 
    set @month = NULLIF(@month - 1, 0) 

set @d = DATEDIFF(day, DATEADD(month, ISNULL(@month, 0), DATEADD(year, ISNULL(@year, 0), @d1)), @d2) 

SELECT ISNULL(cast(@year as nvarchar) + ' year(s) ', '') + ISNULL(cast(@month as nvarchar) + ' month(s) and ', '') + cast(@d as nvarchar) + ' day(s)' 

Anstatt eine Funktion verwenden Sie CASE Aussage, aber meiner Meinung nach verwenden könnte, es sieht schrecklich aus:

SELECT 
    --Years 
    ISNULL(cast(
     CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END 
    AS VARCHAR) + ' year(s) ', '') 
    --Months 
    + ISNULL(cast(

     CASE WHEN DATEADD(month, ISNULL(NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1), @d2), 0), 0), DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1)) > @d2 
      THEN NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1), @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1), @d2), 0) 
      END 
     AS VARCHAR) + ' month(s) ', '') 
    --Days 
    + cast(DATEDIFF(day, DATEADD(month, ISNULL(CASE WHEN DATEADD(month, ISNULL(NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1), @d2), 0), 0), DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1)) > @d2 
      THEN NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1), @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(month, DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END, 0), @d1), @d2), 0) 
      END, 0), DATEADD(year, ISNULL(CASE WHEN DATEADD(year, ISNULL(NULLIF(DATEDIFF(year, @d1, @d2), 0), 0), @d1) > @d2 
      THEN NULLIF(DATEDIFF(year, @d1, @d2) - 1, 0) 
      ELSE NULLIF(DATEDIFF(year, @d1, @d2), 0) 
      END , 0), @d1)), @d2) as nvarchar) + ' day(s)' 
+0

Sie haben Recht, schließlich habe ich beschlossen, eine Funktion zur Berechnung der Datumsbereiche zu erstellen.Einfach, schnell und lesbar. Danke allen! – ron