我有一张名为Students的表,有10条学生记录
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动态解决方案 我尝试使用Cursor,但如果表中有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;
答案 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
);