Вопрос по sql, sql-server-2008 – Могу ли я создать создать глобальную функцию в SQL Server?

5

Можно ли создать функцию в 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   ответа
16

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

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

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

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

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

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

Похожие вопросы