2012-05-23 129 views
5

是否可以在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 

回答

14

您可以創建在主函數(或其他永久性的​​數據庫),然後創建模型數據庫的代名詞:

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))))); 
從頂部

所以:

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; 

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 

我們在每個數據庫中創建一個同義詞爲這個

+0

「getDays」不是公認的內置函數名稱。 –

+0

您需要在master中創建函數,然後在現有數據庫(不僅僅是模型)中創建同義詞。在模型中創建它只會在模型中創建同義詞後創建的* new *數據庫中創建函數。並且始終應始終使用模式前綴引用函數或同義詞,因此它應該是'dbo.getDays',而不是'getDays'。 –

+0

我沒有低估這些「返回」的工作方式 –

3

雖然在主創建存儲過程使它們全局可用,這並不爲職能的工作。您需要使用三部分命名約定:

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

爲什麼微軟的功能與存儲過程不同?

+1

在主服務器中創建功能不會使其他數據庫可用。對於存儲過程,這種行爲是正確的,並且只有當'sp_configure'選項'allow updates'設置爲1或過程名爲'sp_ '時。 –

+0

我創建它在主,但我的腳本沒有看到它 –

+0

我搞砸了。 。 。我正在修復答案 –

相關問題