Могу ли я создать создать глобальную функцию в SQL Server?

Можно ли создать функцию в SQL Server, которую я мог бы использовать в любой базе данных на сервере, без добавления префикса базы данных?

Например, с помощью этой функции:

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

Ответы на вопрос(2)

и, это не работает для функций. Вам необходимо использовать соглашение об именовании из трех частей:

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

Почему Microsoft делает функции отличными от хранимых процедур?

 Gordon Linoff23 мая 2012 г., 23:39
Я напортачил . , , Я исправляю ответ
 Артём Царионов23 мая 2012 г., 23:21
Я создал его в master, но мой скрипт его не видит
 Aaron Bertrand23 мая 2012 г., 23:19
Создание функции в master не делает ее доступной для других баз данных. Такое поведение верно для хранимых процедур, и только когдаsp_configure вариантallow updates установлен в 1, или процедура называетсяsp_<something>.
 Aaron Bertrand23 мая 2012 г., 23:51
Не в 2000 году не было. Вся эта архитектура была заменена в 2005 году, где динамические объекты управления (как функции, так и представления)являютс глобально доступно, но не через тот же механизм. Системные процедуры все еще работают таким образом по причинам обратной совместимости, а не потому, что это правильный путь, и я не ожидаю, что какие-либо процедуры sp_ (или как они работают внутри) изменятся в будущем, кроме прекращения действия ' разрешить обновления или пометить взлом системных объектов.
 Gordon Linoff23 мая 2012 г., 23:46
Аарон, это хороший ответ, но почему бы им не сделать то же самое для функций? Конечно, есть системные функции, которые также выигрывают от доступности по всему миру.
Решение Вопроса

а затем создать синоним в базе данных модели:

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

Это создаст синоним функции в любом Новый базы данных, но для существующих баз данных (или баз данных, подключенных или восстановленных в будущем) вам необходимо скопировать синоним туда. Это позволит вам ссылаться на объект с именем, состоящим из двух частей, в любой базе данных, сохраняя при этом только одну копию кода.

Кроме того, ваш код может быть гораздо более кратким:

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

Так сверху:

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

Теперь, чтобы создать синоним для этого в каждой базе данных:

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;
 Артём Царионов23 мая 2012 г., 23:23
'getDays' не является распознанным именем встроенной функции.
 Aaron Bertrand23 мая 2012 г., 23:25
Вам нужно создать функцию в master, затем создать синоним в существующих базах данных (не только модель). Создание его в модели только создает функцию в Новый базы данных, созданные после создания синонима в модели. И вы всегда должны всегда ссылаться на функции или синонимы с префиксом схемы, поэтому это должно бытьdbo.getDays, неgetDays.
 Артём Царионов23 мая 2012 г., 23:48
а ну понятно
 Aaron Bertrand23 мая 2012 г., 23:36
Получает те же результаты ... работает изнутри, вычитает (1-@dateата @) от@date чтобы получить первое число этого месяца. Добавьте месяц, это первое число следующего месяца. Затем вычтите день. Это последний день месяца @ date. DATEPART (DAY) извлекает день (например, 31 для @date = '2005-05-что угодно') ...
 Артём Царионов23 мая 2012 г., 23:30
Я не понимаю, как этиreturn работае

Ваш ответ на вопрос