2017-10-08 60 views
0

我已经有10条学生添加行基于每月SQL的天

ID StudentName 
1 Student a 
2 Student b 
- ------ - 
10 Student N 

的学生表命名现在我想根据天这10名学生加入到另一个表如一个月

ID StudentName DayOfMonth 
1 Student a  1 
2 Student a  2 
- ---------  - 
- Student a  31 
- Student b   1 
- ------- b   31 

并为所有的学生没有任何SQL动态解决方案 我使用光标尝试,但如果有55名学生在一个表中它大约需要2分钟。虽然我在执行proc时检查了表,但它在几秒钟内生成1705行,即(55x31),但它在挂起或什么时候会作出反应,2分钟后显示成功消息。 任何帮助将不胜感激。

@fkStudentID int, 
@fkClassID int, 
@fkSessionID int, 
@Dated date, 

AS 
Declare @Days as int 
Set @Days = DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@Dated),0))) 
Declare @OffSet as int 
DECLARE @MyCursor CURSOR; 
DECLARE @MyField int; 
BEGIN 
SET @MyCursor = CURSOR FOR 
select fkStudentID from dbo.tblAdmission 
    where fkClassID = @fkClassID and fkSessionID = @fkSessionID 

OPEN @MyCursor 
FETCH NEXT FROM @MyCursor 
    INTO @MyField 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    While(@OffSet <= @Days) 
    Begin 

     if(IsNull((Select count(RegisterID) from tblRegister where @MyField = fkStudentID and fkClassID = @fkClassID and fkSessionID = @fkSessionID and [Dayofmonth] = @OffSet),0) = 0) 
     Begin 
      Insert into tblRegister (fkStudentID, fkClassID, fkSessionID, [DayOfMonth], Dated) values (@MyField, @fkClassID, @fkSessionID, @OffSet, DATEADD(DAY, (@OffSet - 1), DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))) 
     End 
     Set @OffSet = @OffSet + 1 
    End 
    Set @OffSet = 1 
FETCH NEXT FROM @MyCursor 
    INTO @MyField 

END; 

CLOSE @MyCursor ; 
DEALLOCATE @MyCursor; 
END; 
+1

这对我们来说是一个挑战,可以帮助解决您的代码而不会看到它。将proc代码与表DDL一起发布。我希望基于集合的笛卡尔积(交叉连接)查询在一秒之内运行。桌子上有触发器吗? –

+0

请检查上面的程序代码 –

回答

1

我不知道为什么你看到PROC结束前的延迟,但最好是使用基于集合的查询,而不是光标尽可能获得最佳的性能。我希望下面的示例只要有适当的索引(理想情况下,dbo.tblAdmission fkClassID和fkSessionID列上的唯一聚簇索引以及dbo.tblRegister fkStudentID,fkClassID,fkSessionID和DayOfMonth上的唯一索引)。

CREATE PROC dbo.Example 
    @fkClassID int, 
    @fkSessionID int, 
    @Dated date 
AS 

INSERT INTO dbo.tblRegister 
    (
     fkStudentID 
    , fkClassID 
    , fkSessionID 
    , DayOfMonth 
    , Dated 
    ) 
SELECT 
     a.fkStudentID 
    , a.fkClassID 
    , a.fkSessionID 
    , o.offset 
    , DATEADD(DAY, (o.offset - 1), DATEADD(MONTH, DATEDIFF(MONTH, '', GETDATE()), '')) 
FROM dbo.tblAdmission AS a 
CROSS JOIN (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10) 
       ,(11),(12),(13),(14),(15),(16),(17),(18),(19),(20) 
       ,(21),(22),(23),(24),(25),(26),(27),(28),(29),(30),(31)) AS o(offset) 
WHERE 
    a.fkClassID = @fkClassID 
    AND a.fkSessionID = @fkSessionID 
    AND o.offset <= DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,-1,@Dated),0))) 
    AND NOT EXISTS(
     SELECT 1 
     FROM dbo.tblRegister AS r 
     WHERE 
      r.fkStudentID = a.fkStudentID 
      AND r.fkClassID = a.fkClassID 
      AND r.fkSessionID = a.fkSessionID 
      AND [Dayofmonth] = o.offset 
     ); 
+0

Thx丹非常赞赏我看起来不错一件事在某些情况下,某些情况下,您可能会根据月份来确定月份的天数值。 –