起初,我为我糟糕的英语道歉。
问题是 -
在我的数据库中,我有一个包含307763行的表。我每天都需要处理每一行。为了处理行,我在数据库中写了一个SQL查询到SELECT,INSERT和UPDATE。查询的执行时间是 30分到 1小时
然后我创建了一个Visual Studio控制台应用程序来运行该过程。
出现问题。在App.Config中,数据库连接超时有30秒的时间限制。我还尝试将值设为0。
是否有任何安全方法可以保持连接打开1小时或以其他任何方式解决问题?
以下是查询:
DECLARE @totalEmployee AS INT;
DECLARE @i AS INT=1;
DECLARE @employee TABLE
(
Id INT PRIMARY KEY IDENTITY(1,1),
SystemId VARCHAR(30),
PreRecruitmentEmployeeId VARCHAR(30),
DOJ DATETIME,
DOS DATETIME,
ProbationConfirmEntryDate DATETIME
)
INSERT INTO @employee
SELECT EI.SystemId, EI.PreRecruitmentEmployeeId, EI.DOJ, EI.DOS, EI.ProbationConfirmEntryDate FROM EmployeeInformation EI WHERE EI.EmployeeStatus='Active';
SELECT @totalEmployee=COUNT(*) FROM @employee;
WHILE @i<= @totalEmployee
BEGIN
UPDATE EmployeeDocument SET
DueProcessDateTime=CASE WHEN ED.DueProcessDateTime IS NULL THEN GETDATE() ELSE ED.DueProcessDateTime END,
IsMailSend=CASE WHEN ED.DueProcessDateTime IS NULL THEN 1 ELSE ED.IsMailSend END,
DueDate=
CASE
WHEN CD.DependateDate='AsAndWhen' THEN NULL
WHEN CD.DependateDate='AppointmentDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.ApprovedDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.ApprovedDateTime)
END
END
WHEN CD.DependateDate='AgreedJoinDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.AgreedDOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.AgreedDOJ)
END
END
WHEN CD.DependateDate='ResignationApplyDate' THEN (SELECT TOP(1) CASE WHEN ResignationDate<>'' THEN DATEADD(DAY, CD.LeadOrLagDays,ResignationDate)
ELSE NULL END FROM TRN.Resignation WHERE EmployeeId=E.SystemId ORDER BY ResignationDate DESC)
WHEN CD.DependateDate='ApprovedResignationEffectiveDate' THEN (SELECT TOP(1) CASE WHEN ApprovedEffectiveDate<>'' THEN DATEADD(DAY, CD.LeadOrLagDays,ApprovedEffectiveDate)
ELSE NULL END FROM TRN.Resignation WHERE EmployeeId=E.SystemId ORDER BY ApprovedEffectiveDate DESC)
WHEN CD.DependateDate='JoiningDate' AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ)
WHEN CD.DependateDate='LetterOfIndentDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.SelectionDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.SelectionDateTime)
END
END
WHEN CD.DependateDate='ProfileSubmit' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.SelectionDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.SelectionDateTime)
END
END
WHEN CD.DependateDate='ProbitionPeriodConfirmationDate' AND E.ProbationConfirmEntryDate IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.ProbationConfirmEntryDate)
WHEN CD.DependateDate='PromotionDate' THEN NULL
WHEN CD.DependateDate='SeparationDate' AND E.DOS IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOS)
WHEN CD.DependateDate='SelectionDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.SelectionDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.SelectionDateTime)
END
END
END
FROM EmployeeDocument ED
JOIN HKP.ComplianceDocument CD ON CD.Id=ED.ComplianceDocumentId
LEFT JOIN @employee E ON E.SystemId=ED.EmpSystemID
LEFT JOIN PreRecruitmentEmployee PRE ON PRE.Id=E.PreRecruitmentEmployeeId
WHERE E.Id=@i AND ED.FileId IS NULL
SET @i = @i + 1;
END
答案 0 :(得分:2)
既然我们可以看到你的sql语句,我们可以建议一个更好的方法。
您当前的SQL语句正在使用循环,这意味着在@Employee
表变量中的每个记录运行一次。这种程序方法被称为RBAR - (RBAR发音为“ree-bar”,并且是“按行划分行”的“Modenism” - 由Jeff Moden创建 - 一位SQL大师) - 因为它是,嗯,痛苦地慢。 (这里有one of many articles关于这个主题的更多信息)
SQL不适用于这种方法。相反,它适用于基于集合的方法 - 这意味着您可以让它在一组记录上工作,而不是逐个进行。
所以这里是我认为你的sql语句应该是什么样的(注意我用一个简单的派生表交换了@Employees
表变量,所以没有必要担心这个)。
请注意我无法对此进行测试,因为您没有提供样本数据或所需的结果,因此您需要自己进行测试 - 但原则是 - 当您离开时不要去RBAR可以避免它。
UPDATE EmployeeDocument
SET DueProcessDateTime = CASE WHEN ED.DueProcessDateTime IS NULL THEN GETDATE() ELSE ED.DueProcessDateTime END,
IsMailSend = CASE WHEN ED.DueProcessDateTime IS NULL THEN 1 ELSE ED.IsMailSend END,
DueDate =
CASE
WHEN CD.DependateDate='AsAndWhen' THEN NULL
WHEN CD.DependateDate='AppointmentDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.ApprovedDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.ApprovedDateTime)
END
END
WHEN CD.DependateDate='AgreedJoinDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.AgreedDOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.AgreedDOJ)
END
END
WHEN CD.DependateDate='ResignationApplyDate' THEN (SELECT TOP(1) CASE WHEN ResignationDate<>'' THEN DATEADD(DAY, CD.LeadOrLagDays,ResignationDate)
ELSE NULL END FROM TRN.Resignation WHERE EmployeeId=E.SystemId ORDER BY ResignationDate DESC)
WHEN CD.DependateDate='ApprovedResignationEffectiveDate' THEN (SELECT TOP(1) CASE WHEN ApprovedEffectiveDate<>'' THEN DATEADD(DAY, CD.LeadOrLagDays,ApprovedEffectiveDate)
ELSE NULL END FROM TRN.Resignation WHERE EmployeeId=E.SystemId ORDER BY ApprovedEffectiveDate DESC)
WHEN CD.DependateDate='JoiningDate' AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ)
WHEN CD.DependateDate='LetterOfIndentDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.SelectionDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.SelectionDateTime)
END
END
WHEN CD.DependateDate='ProfileSubmit' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.SelectionDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.SelectionDateTime)
END
END
WHEN CD.DependateDate='ProbitionPeriodConfirmationDate' AND E.ProbationConfirmEntryDate IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.ProbationConfirmEntryDate)
WHEN CD.DependateDate='PromotionDate' THEN NULL
WHEN CD.DependateDate='SeparationDate' AND E.DOS IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOS)
WHEN CD.DependateDate='SelectionDate' THEN
CASE WHEN E.PreRecruitmentEmployeeId IS NULL AND E.DOJ IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, E.DOJ) ELSE
CASE WHEN PRE.SelectionDateTime IS NOT NULL THEN DATEADD(DAY, CD.LeadOrLagDays, PRE.SelectionDateTime)
END
END
END
FROM EmployeeDocument ED
JOIN HKP.ComplianceDocument CD ON CD.Id=ED.ComplianceDocumentId
LEFT JOIN
(
SELECT EI.SystemId, EI.PreRecruitmentEmployeeId, EI.DOJ, EI.DOS, EI.ProbationConfirmEntryDate
FROM EmployeeInformation EI
WHERE EI.EmployeeStatus='Active'
) E ON E.SystemId=ED.EmpSystemID
LEFT JOIN PreRecruitmentEmployee PRE ON PRE.Id=E.PreRecruitmentEmployeeId
WHERE ED.FileId IS NULL