9

データベースプレフィックスを追加せずに、サーバー上の任意のデータベースで使用できる関数を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
4

2 に答える 2

19

マスター(または他の永続的なデータベース)で関数を作成してから、モデルデータベースでシノニムを作成できます。

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

これにより、新しいデータベースの関数の同義語が作成されますが、既存のデータベース(または将来接続または復元されるデータベース)の場合は、そこに同義語をコピーする必要があります。これにより、コードのコピーを1つだけ保存するだけで、任意のデータベースで2つの部分からなる名前でオブジェクトを参照できるようになります。

余談ですが、コードはもっと簡潔になる可能性があります。

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

だから上から:

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

次に、各データベースでこれの同義語を作成します。

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;
于 2012-05-23T21:21:24.790 に答える
5

マスターでストアドプロシージャを作成すると、それらはグローバルに使用可能になりますが、これは関数では機能しません。3つの部分からなる命名規則を使用する必要があります。

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

マイクロソフトが関数をストアドプロシージャとは異なるものにするのはなぜですか?

于 2012-05-23T21:18:06.493 に答える