我从此论坛的一位专家那里获得了以下代码(工作正常)。因此,我想做的是进一步修改此查询,以相同的方式获取日期,但适用于所有任务。数据库中有一个名为“ TASK”的表,每个task_id都有一个clndr_id和proj_id。所需的输出将是(proj_id,task_id,clndr_id,date_Value),所以我认为我们需要添加另一个WHILE来获取TASK表中所有任务的所有日期。我希望@CurseStacker或其他任何人都可以帮助:) ..谢谢。
ALTER FUNCTION [dbo].[GetProjectDates]
(
@project_name varchar(50)
)
RETURNS @temp_tb TABLE([proj_id] int, [clndr_id] int , [date_value] date)
AS
BEGIN
-- Add the SELECT statement with parameter references here
DECLARE @project_id int
DECLARE @clndr_id int
DECLARE @walker int = 0
DECLARE @holder varchar(MAX)
DECLARE @date date
DECLARE @data varchar(MAX)
SELECT @project_id = [p].[proj_id]
,@clndr_id = [p].[clndr_id]
,@holder = [c].[clndr_data]
FROM [PMDB].[dbo].[PROJECT] AS [p]
INNER JOIN [PMDB].[dbo].[CALENDAR] AS [c] ON [p].[clndr_id] = [c].[clndr_id]
WHERE [p].[proj_short_name] = @project_name
WHILE @walker <> LEN(@holder) + 1
BEGIN
IF SUBSTRING(@holder, @walker, 2) = 'd|'
BEGIN
SET @data = SUBSTRING(@holder, @walker, 10)
IF SUBSTRING(@data, LEN(@data) - 2, 3) = ')()'
BEGIN
SET @date = DATEADD(D, CAST(SUBSTRING(@data, 3, 5) AS int) -2, '01/01/1900')
INSERT INTO @temp_tb VALUES (@project_id, @clndr_id, @date)
END
END
SET @walker = @walker + 1
END
RETURN
END
GO
因此,“ TASK”表包括(proj_id,task_id,clndr_id),并且从“ Calendar”表中,我们可以通过链接到任务表中的proj_id获得clndr_data(上面的代码获取了clndr_data中“ d |”和“ )()'仅适用于一个clndr_id,它可以正常工作'现在我需要执行同样的操作,但是需要多个日历;
proj_id task_id clndr_id clndr_data
4917 310449 7143 (0||CalendarData()(.....
4917 310450 7144 (0||CalendarData()(.....
4917 310451 7149 (0||CalendarData()(.....
所需结果(假设clndr_id 7143在'd |'和')()'之间只有2个日期,clndr_id 7144有3个日期,而cldnr_id 7149有2个日期)只是一个假设
proj_id task_id clndr_id date
4917 310449 7143 2018-09-24
4917 310449 7143 2018-09-25
4917 310450 7144 2018-09-26
4917 310450 7144 2018-10-01
4917 310450 7144 2018-10-02
4917 310451 7149 2018-10-03
4917 310451 7149 2018-10-04
答案 0 :(得分:0)
尝试如下操作:
ALTER FUNCTION [dbo].[GetProjectDates]
(
@project_name varchar(50)
)
RETURNS @temp_tb TABLE([proj_id] int, [task_id] int, [clndr_id] int , [date_value] date)
AS
BEGIN
-- Add the SELECT statement with parameter references here
DECLARE @project_id int
DECLARE @task_id int
DECLARE @clndr_id int
DECLARE @walker int = 0
DECLARE @holder varchar(MAX) = ''
DECLARE @date date
DECLARE @data varchar(MAX)
declare @tab table (project_id int, task_id int, clndr_id int, holder varchar(max))
insert into @tab
SELECT [T].[proj_id] as project_id
,[T].[task_id] as task_id
,[c].[clndr_id] as clndr_id
,[c].[clndr_data] as holder
FROM [PMDB].[dbo].[TASK] as [T]
INNER JOIN [PMDB].[dbo].[CALENDAR] AS [c] ON [T].[clndr_id] = [c].[clndr_id] and [T].[Proj_id] = [c].[proj_id]
WHERE [T].[proj_id] = (select proj_id FROM [PMDB].[dbo].[PROJECT] where [proj_short_name] = @project_name)
declare @cur_task int, @cur_clndr int
set @cur_task = (select top 1 task_id from @tab)
set @cur_clndr = (select top 1 clndr_id from @tab where task_id = @task_id)
set @holder = (select top 1 holder from @tab where task_id = @task_id)
while ((select count(1) from @tab) > 0)
begin
print 'Current loop running for Task_Id' + convert(varchar(10), @cur_task)
WHILE @walker <> LEN(@holder) + 1
BEGIN
IF SUBSTRING(@holder, @walker, 2) = 'd|'
BEGIN
SET @data = SUBSTRING(@holder, @walker, 10)
IF SUBSTRING(@data, LEN(@data) - 2, 3) = ')()'
BEGIN
SET @date = DATEADD(D, CAST(SUBSTRING(@data, 3, 5) AS int) -2, '01/01/1900')
INSERT INTO @temp_tb VALUES (@project_id, @task_id, @clndr_id, @date)
END
END
SET @walker = @walker + 1
END
delete @tab where task_id = @cur_task
set @cur_task = (select top 1 task_id from @tab)
set @cur_clndr = (select top 1 clndr_id from @tab where task_id = @task_id)
set @holder = (select top 1 holder from @tab where task_id = @task_id)
set @walker = 0
end
RETURN
END