Is it possible to create a function in SQL Server which I could use in any database on the server, without adding the database prefix?
For example, with this function:
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
You can create the function in master (or some other permanent database), and then create a synonym in the model database:
USE model;
GO
CREATE SYNONYM dbo.getDays FOR master.dbo.getDays;
This will create a synonym to the function in any new databases, but for existing databases (or databases attached or restored in the future) you'll need to copy the synonym there. This will allow you to reference the object with a two-part name in any database, while only having to store one copy of the code.
As an aside, your code could be much more concise:
RETURN (SELECT DATEPART(DAY, DATEADD(DAY, -1,
DATEADD(MONTH, 1, DATEADD(DAY, 1-DAY(@date), @date)))));
So from the top:
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
Now to create a synonym for this in each database:
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;
Although creating stored procedures in master makes them globally available, this does not work for functions. You need to use the three-part naming convention:
select <dbname>.<schema>.getDays(...)
Why would Microsoft make functions different from stored procedures?