7

この質問の伝統とドキュメントに照らして、この関数を決定論的にするにはどうすればよいですか。

ALTER FUNCTION [udf_DateTimeFromDataDtID]
(
    @DATA_DT_ID int -- In form YYYYMMDD
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
    RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID))
END

またはこれ(文字列/日付リテラルのため-はい、「1900-01-01」も試しました):

ALTER FUNCTION udf_CappedDate
(
    @DateTimeIn datetime
)
RETURNS datetime
WITH SCHEMABINDING
AS
BEGIN
    IF @DateTimeIn < '1/1/1900'
        RETURN '1/1/1900'
    ELSE IF @DateTimeIn > '1/1/2100'
        RETURN '1/1/2100'

    RETURN @DateTimeIn
END
4

2 に答える 2

7

BOL は、スタイルパラメータが指定されている場合、datetimes で決定論CONVERT 的であると言います。したがって、最初の UDF を次のように変更すると:

RETURN CONVERT(datetime, CONVERT(varchar, @DATA_DT_ID), 112)

ドキュメントを正しく理解していれば、決定論的である必要があります。

おそらく、同じトリックを 2 番目の UDF で使用できます。

IF @DateTimeIn < CONVERT(datetime, '1/1/1900', 101)
    RETURN CONVERT(datetime, '1/1/1900', 101)

T-SQL で日時リテラルを指定する方法があればいいのにと思います。

編集

コメントで Arvo が指摘したように (ありがとう、Arvo)、ODBC タイムスタンプ リテラル形式は (OLE DB を使用している場合でも) 使用できるため、上記の 2 番目の関数は次のように記述した方が適切です。

IF @DateTimeIn < {d '1900-01-01'}
    RETURN {d '1900-01-01'}
...etc.

日時への変換は、実行時ではなくコンパイル時に行われます。日付の形式は非常に具体的でなければならないことに注意してください (日時データ型への Arvo のリンクを参照してください)。

 d yyyy-mm-dd
 t hh:mm:ss[.fff]
ts yyyy-mm-dd hh:mm:ss[.fff]

于 2008-11-21T20:50:02.543 に答える
5

リンクした記事から:

決定論的であるためには、スタイル パラメーターは定数でなければなりません。さらに、スタイル 20 と 21 を除き、100 以下のスタイルは非決定論的です。スタイル 106、107、109、および 113 を除き、100 を超えるスタイルは決定論的です。

datetime への変換でスタイル パラメーターを使用する必要があります。

例えば:

CONVERT(datetime, '2008-01-01', 121)

121を使用しないことを除いて...

于 2008-11-21T20:35:20.013 に答える