Pytanie w sprawie sql, sql-server-2008 – Czy mogę utworzyć globalną funkcję w SQL Server?

5

Czy możliwe jest utworzenie funkcji w SQL Server, której mógłbym użyć w dowolnej bazie danych na serwerze, bez dodawania prefiksu bazy danych?

Na przykład z tą funkcją:

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

Twoja odpowiedź

2   odpowiedź
16

a następnie utworzyć synonim w bazie danych modelu:

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

Spowoduje to utworzenie synonimu funkcji w dowolnymNowy bazy danych, ale w przypadku istniejących baz danych (lub baz danych dołączonych lub przywróconych w przyszłości) należy tam skopiować synonim. Pozwoli to na odwołanie się do obiektu z dwuczęściową nazwą w dowolnej bazie danych, podczas gdy wystarczy przechowywać jedną kopię kodu.

Na marginesie, Twój kod może być bardziej zwięzły:

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

Więc z góry:

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

Teraz utwórz synonim tego w każdej bazie danych:

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;
rozumiem. Артём Царионов
Uzyskuje takie same wyniki ... działa od wewnątrz, odejmuje (1-@datedata) od@date zdobyć pierwszy tego miesiąca. Dodaj miesiąc, to pierwszy z następnego miesiąca. Następnie odejmij dzień. To ostatni dzień miesiąca @ date. DATEPART (DAY) wydobywa dzień (np. 31 dla @date = '2005-05-anything') ... Aaron Bertrand
Musisz utworzyć funkcję w Master, a następnie utworzyć synonim w istniejących bazach danych (nie tylko w modelu). Utworzenie go w modelu tworzy tylko funkcję wNowy bazy danych tworzone po utworzeniu synonimu w modelu. Zawsze powinieneś zawsze ZAWSZE odwoływać się do funkcji lub synonimów z przedrostkiem schematu, tak powinno byćdbo.getDays, niegetDays. Aaron Bertrand
Nie rozumiem, jak to jestreturn Prace Артём Царионов
„getDays” nie jest uznaną nazwą wbudowanej funkcji. Артём Царионов
3

obalnie dostępnymi, nie działa to w przypadku funkcji. Musisz użyć trzyczęściowej konwencji nazewnictwa:

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

Dlaczego Microsoft miałby robić funkcje inne niż procedury składowane?

Utworzenie funkcji w Master nie udostępnia jej innym bazom danych. To zachowanie jest prawdziwe dla procedur przechowywanych i tylko wtedy, gdysp_configure opcjaallow updates jest ustawiona na 1 lub nazwa procedurysp_<something>. Aaron Bertrand
Aaron, to świetna odpowiedź, ale dlaczego nie zrobiliby tego samego dla funkcji? Z pewnością istnieją funkcje systemowe, które również korzystają z globalnej dostępności. Gordon Linoff
Nie w 2000 roku nie było. Ta cała architektura została zastąpiona w 2005 r., Gdzie dynamiczne obiekty zarządzania (zarówno funkcje, jak i widoki)są globalnie dostępne, ale nie przez ten sam mechanizm. Procedury systemowe nadal działają w ten sposób ze względu na wsteczną kompatybilność, nie dlatego, że jest to właściwa droga, i nie spodziewałbym się, że któraś z procedur sp_ (lub tego, jak działają wewnętrznie) zmieni się w przyszłości, poza przerwaniem zezwalaj na aktualizacje lub zaznacz hacki obiektów systemowych. Aaron Bertrand
Funkcjonalność, która sprawia, że ​​procedury składowane są dostępne na całym świecie, nigdy nie była przeznaczona dla klientów, ponieważ była przeznaczona dla procedur przechowywanych w systemie, takich jak sp_help, aby istniały w jednym miejscu, ale aby móc działać w kontekście dowolnej bazy danych. Ta funkcja nigdy nie była potrzebna wewnętrznie dla tabel, widoków, funkcji itp., Więc po prostu nigdy nie istniała. Nie sądzę, aby korzystanie z tej „funkcji” było oficjalnie obsługiwane i może nie działać w niektórych przyszłych wersjach. Aaron Bertrand

Powiązane pytania