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
It is not possible to declare global variables in SQL Server. Sql server has a concept of global variables, but they are system defined and can not be extended.
You create SQL scalar functions when you are designing a database or developing applications. SQL scalar functions are useful to have when there is an identifiable benefit to encapsulating a piece of reusable logic. These functions are called by SQL statements that are used within applications and database objects.
A global variable is a named memory variable that you access through SQL statements. Global variables let you share relational data between SQL statements without the need for application logic to support this data transfer.
Global variables are pre-defined system functions. Their names begin with an @@ prefix. The server maintains the values in these variables. Global variables return various pieces of information about the current user environment for SQL Server.
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With