11

関数で DATEFIRST を設定したいのですが、許可されていません。

SET DATEFIRST 1

SP にコードを追加し、関数から SP を呼び出すことはできますが、それを行うことに熱心ではありません。

関数を呼び出す前に DATEFIRST を設定できますが、それもやりたくありません。

他の回避策はありますか?

編集

以下は、FUNCTION で使用して、その月の合計稼働日を返すコードです。しかし、DATEFIRST のため、このコードを FUNCTION に追加することはできません

DECLARE @my int
DECLARE @myDeduct int
DECLARE @day INT
DECLARE @mydate DATETIME
DECLARE @TotalDays INT

SET @mydate = GETDATE()

SET @myDeduct = 0
IF (@@DATEFIRST + DATEPART(DW, @mydate)) % 7 not in (0,1)
SET DateFirst 1 -- Set it monday=1 (value)

--Saturday and Sunday on the first and last day of a month will Deduct 1
IF (DATEPART(weekday,(DATEADD(dd,-(DAY(@mydate)-1),@mydate))) > 5)
SET @myDeduct = @myDeduct + 1

IF (DATEPART(weekday,(DATEADD(dd,-(DAY(DATEADD(mm,1,@mydate))),DATEADD(mm,1,@mydate)))) > 5)
SET @myDeduct = @myDeduct + 1

SET @my = day(DATEADD(dd,-(DAY(DATEADD(mm,1,@mydate))),DATEADD(mm,1,@mydate)))

Set @TotalDays = (select (((@my/7) * 5 + (@my%7)) - @myDeduct))

Select @TotalDays
4

4 に答える 4

10

私の通常の回避策は、比較に「既知の適切な」日付を使用することです。

たとえば、日付が土曜日であることを確認する必要があるとします。DATEFIRSTまたは言語設定 (を使用するため) に依存するのでDATENAMEはなく、代わりに次のように言います。

DATEPART(weekday,DateToCheck) = DATEPART(weekday,'20120714')

2012 年 7 月 14 日は土曜日だったので、外部設定に頼らずにチェックを実行しました。


この式(DATEPART(weekday,DateToCheck) + @@DATEFIRST) % 7は常に、土曜日の場合は 0、日曜日の場合は 1、月曜日の場合は 2 などの値を生成します。

したがって、テーブルを作成することをお勧めします。

CREATE TABLE WorkingDays (
    NormalisedDay int not null,
    DaysInMonth int not null,
    WorkingDays int not null
)

このテーブルへの入力は、1 回限りの演習です。NormalisedDay上記の式で計算された値になります。

DaysInMonth特定の日付を計算するには、次の式を使用できます。

DATEDIFF(day,
      DATEADD(month,DATEDIFF(month,0,DateToCheck),0),
      DATEADD(month,DATEDIFF(month,'20010101',DateToCheck),'20010201'))

これで、関数で行う必要があるのは、テーブル内の値を検索することだけです。

(もちろん、DaysInMonth28 であるすべての行は、結果として 20 になります。生成するのに少し作業が必要なのは、29、30、および 31 の行だけです)

于 2012-09-19T07:23:54.427 に答える
0

別の方法として、パラメータとして週の最初の曜日の値を明示的に指定し、@@DATEFIRST設定に依存しないようにすることもできます。次の式を使用して、関数でそれを実現できます。

(DATEPART(dw, GETDATE()) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1

@WeekStartDay、システムで使用する週の最初の曜日です (1 から 7 で、月曜日から日曜日を意味します)。

簡単に再利用できるように、以下の関数にラップしました。

CREATE FUNCTION [dbo].[GetDayInWeek](@InputDateTime DATETIME, @WeekStartDay INT)
RETURNS INT
AS
BEGIN
    --Note: @WeekStartDay is number from [1 - 7] which is from Monday to Sunday
    RETURN (DATEPART(dw, @InputDateTime) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1 
END

使用例: GetDayInWeek('2019-02-04 00:00:00', 1)

これは以下と同等です (ただし、DATEFIRST 設定には依存しません)。

SET DATEFIRST 1
DATEPART(dw, '2019-02-04 00:00:00')
于 2019-02-07T15:46:18.367 に答える