sql 工作日触发日期范围
sql trigger daterange with weekdays
我在 MSSQL(2012) 数据库上有 2 个表("tblA" 和 "tblB")。在 "tblA" 上插入后,我希望触发器在 "tblB" 上自动生成日期在 "tblA" 的 STARTDATE 和 ENDDATE 之间的记录,但仅在 "tblA"[=13 上选择的工作日=]
例如 "tblA":
tblA_ID: 99
CAT: TEXT1
STARTDATE: 01/01/2015
ENDDATE: 31/01/2015
MONDAY: true
TUESDAY: false
WEDNESDAY: false
THURSDAY: false
FRIDAY: true
SATURDAY: false
SUNDAY: false
"tblB" 应该得到
1 99 TEXT1 02/01/2015 (=Friday)
2 99 TEXT1 04/01/2015 (=Monday)
3 99 TEXT1 09/01/2015 (=Friday)
4 99 TEXT1 11/01/2015 (=Monday)
5 99 TEXT1 16/01/2015 (=Friday)
6 99 TEXT1 28/01/2015 (=Monday)
7 99 TEXT1 23/01/2015 (=Friday)
8 99 TEXT1 25/01/2015 (=Monday)
9 99 TEXT1 30/01/2015 (=Friday)
CREATE TABLE [dbo].[tblA]
(
[tblA_ID] INT NOT NULL IDENTITY,
[tblA_CAT] NVARCHAR(50) NULL,
[tblA_STARTDATE] DATE NULL,
[tblA_ENDDATE] DATE NULL,
[tblA_MONDAY] BIT NULL,
[tblA_TUESDAY] BIT NULL,
[tblA_WEDNESDAY] BIT NULL,
[tblA_THURSDAY] BIT NULL,
[tblA_FRIDAY] BIT NULL,
[tblA_SATURDAY] BIT NULL,
[tblA_SUNDAY] BIT NULL,
CONSTRAINT [PK_tblA] PRIMARY KEY ([tblA_ID]),
)
CREATE TABLE [dbo].[tblB]
(
[tblB_ID] INT NOT NULL IDENTITY,
[tblA_ID] INT NOT NULL,
[tblB_CAT] NVARCHAR(50) NULL,
[tblB_DATE] DATE NULL,
CONSTRAINT [PK_tblB] PRIMARY KEY ([tblB_ID]),
)
这个触发器应该适合你。它使用递归通用 table 表达式来生成范围内的所有 tblB_DATE
值,然后使用 case 表达式来测试日期名称是否在标记为 true 的那些值中。请注意,这部分取决于系统语言,因此如果您不使用英语,则必须根据您的特定语言调整日期名称文字。
递归通用 table 表达式可替代日历 table,因此如果您有合适的 table 可以作为日期的来源,那么您可以使用相反(它应该提供更好的性能)。
另请注意,代码缺乏错误检查且未优化,因此可能会有所改进。它应该让您了解如何解决您的问题。
CREATE TRIGGER ins_tblb ON [dbo].[tblA] AFTER INSERT AS
BEGIN
WITH dates AS (
SELECT
tblA_ID, tbla_CAT, tbla_STARTDATE, tbla_ENDDATE,
tbla_MONDAY, tbla_TUESDAY, tbla_WEDNESDAY, tbla_THURSDAY,
tbla_FRIDAY, tbla_SATURDAY, tbla_SUNDAY,
tblA_STARTDATE tblB_DATE
FROM inserted
UNION ALL
SELECT tblA_ID, tbla_CAT, tbla_STARTDATE, tbla_ENDDATE,
tbla_MONDAY, tbla_TUESDAY, tbla_WEDNESDAY, tbla_THURSDAY,
tbla_FRIDAY, tbla_SATURDAY, tbla_SUNDAY,
DATEADD(DAY, 1, tblB_DATE) tblB_DATE
FROM dates
WHERE dates.tblB_DATE <= tblA_ENDDATE
)
INSERT tblB (tblA_ID, tblB_CAT, tblB_DATE)
SELECT tblA_ID, tblA_CAT, tblB_DATE
FROM dates
WHERE DATENAME(DW,tblB_DATE) IN (
CASE WHEN tblA_MONDAY = 1
THEN N'Monday' END,
CASE WHEN tblA_TUESDAY = 1
THEN N'Tuesday' END,
CASE WHEN tblA_WEDNESDAY = 1
THEN N'Wednesday' END,
CASE WHEN tblA_THURSDAY = 1
THEN N'Thursday' END,
CASE WHEN tblA_FRIDAY = 1
THEN N'Friday' END,
CASE WHEN tblA_SATURDAY = 1
THEN N'Saturday' END,
CASE WHEN tblA_SUNDAY = 1
THEN N'Sunday' END
)
ORDER BY tblA_ID, tblB_DATE
OPTION (MAXRECURSION 0)
END
我在 MSSQL(2012) 数据库上有 2 个表("tblA" 和 "tblB")。在 "tblA" 上插入后,我希望触发器在 "tblB" 上自动生成日期在 "tblA" 的 STARTDATE 和 ENDDATE 之间的记录,但仅在 "tblA"[=13 上选择的工作日=]
例如 "tblA":
tblA_ID: 99
CAT: TEXT1
STARTDATE: 01/01/2015
ENDDATE: 31/01/2015
MONDAY: true
TUESDAY: false
WEDNESDAY: false
THURSDAY: false
FRIDAY: true
SATURDAY: false
SUNDAY: false
"tblB" 应该得到
1 99 TEXT1 02/01/2015 (=Friday)
2 99 TEXT1 04/01/2015 (=Monday)
3 99 TEXT1 09/01/2015 (=Friday)
4 99 TEXT1 11/01/2015 (=Monday)
5 99 TEXT1 16/01/2015 (=Friday)
6 99 TEXT1 28/01/2015 (=Monday)
7 99 TEXT1 23/01/2015 (=Friday)
8 99 TEXT1 25/01/2015 (=Monday)
9 99 TEXT1 30/01/2015 (=Friday)
CREATE TABLE [dbo].[tblA]
(
[tblA_ID] INT NOT NULL IDENTITY,
[tblA_CAT] NVARCHAR(50) NULL,
[tblA_STARTDATE] DATE NULL,
[tblA_ENDDATE] DATE NULL,
[tblA_MONDAY] BIT NULL,
[tblA_TUESDAY] BIT NULL,
[tblA_WEDNESDAY] BIT NULL,
[tblA_THURSDAY] BIT NULL,
[tblA_FRIDAY] BIT NULL,
[tblA_SATURDAY] BIT NULL,
[tblA_SUNDAY] BIT NULL,
CONSTRAINT [PK_tblA] PRIMARY KEY ([tblA_ID]),
)
CREATE TABLE [dbo].[tblB]
(
[tblB_ID] INT NOT NULL IDENTITY,
[tblA_ID] INT NOT NULL,
[tblB_CAT] NVARCHAR(50) NULL,
[tblB_DATE] DATE NULL,
CONSTRAINT [PK_tblB] PRIMARY KEY ([tblB_ID]),
)
这个触发器应该适合你。它使用递归通用 table 表达式来生成范围内的所有 tblB_DATE
值,然后使用 case 表达式来测试日期名称是否在标记为 true 的那些值中。请注意,这部分取决于系统语言,因此如果您不使用英语,则必须根据您的特定语言调整日期名称文字。
递归通用 table 表达式可替代日历 table,因此如果您有合适的 table 可以作为日期的来源,那么您可以使用相反(它应该提供更好的性能)。
另请注意,代码缺乏错误检查且未优化,因此可能会有所改进。它应该让您了解如何解决您的问题。
CREATE TRIGGER ins_tblb ON [dbo].[tblA] AFTER INSERT AS
BEGIN
WITH dates AS (
SELECT
tblA_ID, tbla_CAT, tbla_STARTDATE, tbla_ENDDATE,
tbla_MONDAY, tbla_TUESDAY, tbla_WEDNESDAY, tbla_THURSDAY,
tbla_FRIDAY, tbla_SATURDAY, tbla_SUNDAY,
tblA_STARTDATE tblB_DATE
FROM inserted
UNION ALL
SELECT tblA_ID, tbla_CAT, tbla_STARTDATE, tbla_ENDDATE,
tbla_MONDAY, tbla_TUESDAY, tbla_WEDNESDAY, tbla_THURSDAY,
tbla_FRIDAY, tbla_SATURDAY, tbla_SUNDAY,
DATEADD(DAY, 1, tblB_DATE) tblB_DATE
FROM dates
WHERE dates.tblB_DATE <= tblA_ENDDATE
)
INSERT tblB (tblA_ID, tblB_CAT, tblB_DATE)
SELECT tblA_ID, tblA_CAT, tblB_DATE
FROM dates
WHERE DATENAME(DW,tblB_DATE) IN (
CASE WHEN tblA_MONDAY = 1
THEN N'Monday' END,
CASE WHEN tblA_TUESDAY = 1
THEN N'Tuesday' END,
CASE WHEN tblA_WEDNESDAY = 1
THEN N'Wednesday' END,
CASE WHEN tblA_THURSDAY = 1
THEN N'Thursday' END,
CASE WHEN tblA_FRIDAY = 1
THEN N'Friday' END,
CASE WHEN tblA_SATURDAY = 1
THEN N'Saturday' END,
CASE WHEN tblA_SUNDAY = 1
THEN N'Sunday' END
)
ORDER BY tblA_ID, tblB_DATE
OPTION (MAXRECURSION 0)
END