Pertanyaan Bisakah saya membuat membuat fungsi global di SQL Server?


Apakah mungkin untuk membuat fungsi di SQL Server yang dapat saya gunakan dalam database di server, tanpa menambahkan awalan basis data?

Misalnya, dengan fungsi ini:

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

5
2018-05-23 21:13


asal


Jawaban:


Anda dapat membuat fungsi di master (atau beberapa database permanen lainnya), dan kemudian membuat sinonim dalam database model:

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

Ini akan membuat sinonim ke fungsi di mana saja baru database, tetapi untuk database yang ada (atau database yang terpasang atau dipulihkan di masa depan) Anda harus menyalin sinonim di sana. Ini akan memungkinkan Anda untuk mereferensikan objek dengan nama dua bagian dalam database apa pun, sementara hanya harus menyimpan satu salinan kode.

Sebagai samping, kode Anda bisa jauh lebih ringkas:

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

Jadi dari atas:

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

Sekarang untuk membuat sinonim untuk ini di setiap 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;

14
2018-05-23 21:21



Meskipun membuat prosedur tersimpan di master membuatnya tersedia secara global, ini tidak berfungsi untuk fungsi. Anda perlu menggunakan konvensi penamaan tiga bagian:

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

Mengapa Microsoft membuat fungsi berbeda dari prosedur tersimpan?


3
2018-05-23 21:18