Pregunta sobre sql-server-2008, sql – ¿Puedo crear crear una función global en SQL Server?

5

¿Es posible crear una función en SQL Server que pueda usar en cualquier base de datos del servidor sin agregar el prefijo de la base de datos?

Por ejemplo, con esta función:

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

Tu respuesta

2   la respuesta
16

anente) y luego crear un sinónimo en la base de datos modelo:

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

Esto creará un sinónimo a la función en cualquiernuevo bases de datos, pero para las bases de datos existentes (o bases de datos adjuntas o restauradas en el futuro) deberá copiar el sinónimo allí. Esto le permitirá hacer referencia al objeto con un nombre de dos partes en cualquier base de datos, mientras que solo tendrá que almacenar una copia del código.

Además, su código podría ser mucho más conciso:

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

Así que desde la cima:

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

Ahora para crear un sinónimo para esto en cada base de datos:

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;
No entiendo cómo esosreturn trabajos Артём Царионов
'getDays' no es un nombre de función incorporado reconocido. Артём Царионов
Obtiene los mismos resultados ... trabajando de adentro hacia afuera, reste (1-@datefecha) de@date para conseguir el primero de ese mes. Agrega un mes, ese es el primero del mes siguiente. Luego restar un día. Ese es el último día del mes de @ date. DATEPART (DÍA) extrae el día (por ejemplo, 31 para @date = '2005-05-cualquiera') ... Aaron Bertrand
Oh ya veo. Артём Царионов
Debe crear la función en el maestro y luego crear el sinónimo en las bases de datos existentes (no solo en el modelo). Crearlo en el modelo solo crea la función ennuevo Bases de datos que se crean después de que el sinónimo se ha creado en el modelo. Y siempre, siempre, SIEMPRE debe hacer referencia a las funciones o sinónimos con el prefijo de esquema, por lo que debería serdbo.getDaysnogetDays. Aaron Bertrand
3

e disponibles globalmente, esto no funciona para las funciones. Debe utilizar la convención de nomenclatura de tres partes:

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

¿Por qué Microsoft haría funciones diferentes de los procedimientos almacenados?

La funcionalidad que hace que los procedimientos almacenados estén disponibles en todo el mundo nunca fue realmente destinada para que los clientes la usaran, fue diseñada para que los procedimientos almacenados del sistema como sp_help existan en un solo lugar pero puedan ejecutarse en el contexto de cualquier base de datos. Esta característica nunca fue necesaria internamente para tablas, vistas, funciones, etc., por lo que simplemente nunca existió. No creo que el uso de esta "característica" sea oficialmente compatible, y puede que no funcione en alguna versión futura. Aaron Bertrand
No en el 2000 no hubo. Toda esta arquitectura se reemplazó en 2005, donde los objetos de administración dinámica (tanto funciones como vistas)son Disponible a nivel mundial, pero no a través del mismo mecanismo. Los procedimientos del sistema todavía funcionan de esta manera por razones de compatibilidad con versiones anteriores, no porque sea la forma correcta, y no esperaría que ninguno de los procedimientos sp_ ​​(o cómo funcionan internamente) cambie en el futuro, aparte de la interrupción del ' Permitir actualizaciones o marcar hacks de objetos del sistema. Aaron Bertrand
Lo arruiné . . . Estoy arreglando la respuesta Gordon Linoff
La creación de la función en el maestro no hace que esté disponible para otras bases de datos. Este comportamiento es cierto para los procedimientos almacenados, y solo cuando elsp_configure opciónallow updates se establece en 1, o el procedimiento se denominasp_<something>. Aaron Bertrand

Preguntas relacionadas