3

SQL Server では、DATEADD組み込み関数を別の関数でラップする必要があります。

問題は、この動作を実装する必要があることです:

戻り値の型

戻り値のデータ型は、日付引数のデータ型です[...]

たとえば、datetime引数としてa を渡すと、 aDATEADDが返されますdatetime。を渡すと、dateDATEADD返されますdate

datetime次の例では、常に...が返されます。

create function add_months(@dt date, @interval int) 
   returns datetime
as
begin
   return DATEADD(month, @interval, @dt)
end

これを SQL Server に実装するにはどうすればよいですか?

(編集)

環境

Informix から SQL Server へのデータベース移行を実行しています。ここでの問題はデータベース部分ではなく、コードです。SQL クエリが組み込まれているため、変更が必要なプログラムが何百もあります。これが、使用を避けようとしている主な理由ですDATEADD(MONTH, 1, foo)。この自動変換は、ほとんどの場合単純ですが、場合によっては非常に難しい場合があります。udf を使用すると、informix 関数の名前を置き換えるだけで、より深いリファクタリングを行う必要はありません。

4

2 に答える 2

3

オーバーロードされた関数は使用できません。私はSQL_VARIANTこれに靴べらを入れる方法を考えようとしていますが、私が考えることができるすべてのオプションは、不必要に嫌な合併症につながります。日付を受け取って返す関数と、日時を受け取って返す関数を作成し、適切な関数を呼び出します。精度の低いものは高いものを呼び出すことができるので、コードを複製する必要はありません。

CREATE FUNCTION dbo.add_months_to_datetime
(@dt DATETIME, @interval INT)
RETURNS DATETIME
AS
BEGIN
  RETURN DATEADD(MONTH, @interval, @dt);
END
GO

CREATE FUNCTION dbo.add_months_to_date
(@dt DATE, @interval INT)
RETURNS DATE
AS
BEGIN
  RETURN dbo.add_months_to_datetime(@dt, @interval);
END
GO

または、常に最高の精度(1番目の関数)を使用し、データを提示するときにそれが日付であるか日時であるかを心配します。これは、インライン変換を使用するか、別の関数で適切にラップすることで実行できます。

編集

または、さらに良いことに、この疑わしい値の関数へのすべての呼び出しを適切なインラインdateadd呼び出しに置き換えるだけです。

dbo.add_months(foo, 1)

になる:

DATEADD(MONTH, 1, foo)

希望するほど自動ではありませんが、出力タイプが入力と同じであるという要件を維持することに加えて、クエリ内のどこで使用されているかに応じて、一部のクエリのパフォーマンスも向上する可能性があります。

于 2012-07-05T17:09:49.283 に答える
2

SQL Server のスカラー関数のパフォーマンスが低いため、通常はこれを避けるか、Aaron の手法を使用します。

ただし、その構文が必要な場合は、次のような abomination を使用できます。

create function dbo.add_months(@dt sql_variant, @interval int) 
   returns sql_variant
as
begin
   IF SQL_VARIANT_PROPERTY(@dt, 'BaseType') = 'datetime'
       return DATEADD(month, @interval, CAST(@dt AS DATETIME))
   ELSE IF SQL_VARIANT_PROPERTY(@dt, 'BaseType') = 'date'
       return DATEADD(month, @interval, CAST(@dt AS DATE))
   RETURN null
end

DECLARE @d DATE = '20120705';
DECLARE @dt DATETIME = '20120705 12:30:30';

SELECT dbo.add_months(@d, 1), dbo.add_months(@dt, 1);

この SQLFiddle で、sql_variant からデータを有用なものに変換する際に問題が発生していることがわかります: http://sqlfiddle.com/#!6/f95ba/4

于 2012-07-05T17:16:34.993 に答える