Frage an sql, sql-server-2008 – Kann ich eine globale Funktion in SQL Server erstellen?

5

Ist es möglich, eine Funktion in SQL Server zu erstellen, die ich in einer beliebigen Datenbank auf dem Server verwenden kann, ohne das Datenbankpräfix hinzuzufügen?

Zum Beispiel mit dieser Funktion:

CREATE FUNCTION getDays (@date date)
RETURNS INT
AS
BEGIN

RETURN CASE WHEN MONTH(@date) IN (1, 3, 5, 7, 8, 10, 12) THEN 31
            WHEN MONTH(@date) IN (4, 6, 9, 11) THEN 30
            ELSE CASE WHEN (YEAR(@date) % 4    = 0 AND
                            YEAR(@date) % 100 != 0) OR
                           (YEAR(@date) % 400  = 0)
                      THEN 29
                      ELSE 28
                 END
       END

END

Deine Antwort

2   die antwort
16

Sie können die Funktion in master (oder einer anderen permanenten Datenbank) erstellen und anschließend ein Synonym in der Modelldatenbank erstellen:

USE model;
GO
CREATE SYNONYM dbo.getDays FOR master.dbo.getDays;

Dadurch wird ein Synonym für die Funktion in any erstelltNeu Datenbanken, aber für vorhandene Datenbanken (oder Datenbanken, die angehängt oder in Zukunft wiederhergestellt werden) müssen Sie das Synonym dort kopieren. Auf diese Weise können Sie in jeder Datenbank auf das Objekt mit einem zweiteiligen Namen verweisen, während Sie nur eine Kopie des Codes speichern müssen.

Abgesehen davon könnte Ihr Code viel prägnanter sein:

  RETURN (SELECT DATEPART(DAY, DATEADD(DAY, -1, 
     DATEADD(MONTH, 1, DATEADD(DAY, 1-DAY(@date), @date)))));

Also von oben:

USE [master];
GO
DROP FUNCTION dbo.getDays;
GO
CREATE FUNCTION dbo.getDays
(
    @date DATE
)
RETURNS INT
AS
BEGIN
    RETURN (SELECT DATEPART(DAY, DATEADD(DAY, -1, 
         DATEADD(MONTH, 1, DATEADD(DAY, 1-DAY(@date), @date)))));
END
GO

Erstellen Sie nun in jeder Datenbank ein Synonym dafür:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += CHAR(13) + CHAR(10) 
+ 'USE ' + QUOTENAME(name) + ';

IF OBJECT_ID(''dbo.getDays'', ''FN'') IS NOT NULL
  DROP FUNCTION dbo.getDays;

IF OBJECT_ID(''dbo.getDays'', ''SN'') IS NOT NULL
  DROP SYNONYM dbo.getDays

CREATE SYNONYM dbo.getDays FOR master.dbo.getDays;'
 FROM sys.databases WHERE name <> 'master';

PRINT @sql;

EXEC sp_executesql @sql;
oh ... ich verstehe. Артём Царионов
'getDays' ist kein anerkannter eingebauter Funktionsname. Артём Царионов
Es werden die gleichen Ergebnisse erzielt ... von innen nach außen arbeiten, subtrahieren (1-@dateDatum) von@date den ersten des Monats zu bekommen. Füge einen Monat hinzu, das ist der erste des nächsten Monats. Dann einen Tag abziehen. Das ist der letzte Tag des Monats von @ date. DATEPART (DAY) extrahiert den Tag (z. B. 31 für @date = '2005-05-anything') ... Aaron Bertrand
Ich verstehe nicht, wie diereturn funktioniert Артём Царионов
Sie müssen die Funktion in master erstellen und dann das Synonym in vorhandenen Datenbanken (nicht nur in model) erstellen. Wenn Sie es im Modell erstellen, wird nur die Funktion in erstelltNeu Datenbanken, die erstellt werden, nachdem das Synonym in model erstellt wurde. Und Sie sollten immer, immer, IMMER auf Funktionen oder Synonyme mit dem Schema-Präfix verweisen, so sollte es seindbo.getDaysnichtgetDays. Aaron Bertrand
3

Durch das Erstellen gespeicherter Prozeduren im Master werden sie zwar global verfügbar, dies funktioniert jedoch nicht für Funktionen. Sie müssen die dreiteilige Namenskonvention verwenden:

select <dbname>.<schema>.getDays(...)

Warum sollte Microsoft Funktionen von gespeicherten Prozeduren unterscheiden?

Die Funktionalität, mit der gespeicherte Prozeduren global verfügbar gemacht werden, war für Kunden eigentlich nie vorgesehen. Sie war dafür gedacht, dass gespeicherte Systemprozeduren wie sp_help an einem Ort vorhanden sind, aber im Kontext einer beliebigen Datenbank ausgeführt werden können. Diese Funktion wurde intern nie für Tabellen, Ansichten, Funktionen usw. benötigt, sodass sie einfach nie existierte. Ich glaube nicht, dass die Verwendung dieser "Funktion" offiziell unterstützt wird, und sie funktioniert möglicherweise in zukünftigen Versionen nicht. Aaron Bertrand
Ich vermasselte . . . Ich repariere die Antwort Gordon Linoff
Durch das Erstellen der Funktion im Master wird sie nicht für andere Datenbanken verfügbar gemacht. Dieses Verhalten gilt für gespeicherte Prozeduren und nur, wenn diesp_configure Möglichkeitallow updates wird auf 1 gesetzt, oder die Prozedur wird benanntsp_<something>. Aaron Bertrand
Ich habe es in master erstellt, aber mein Skript sieht es nicht Артём Царионов

Verwandte Fragen