2014-09-24 61 views
0

DBA不喜歡我正在使用case語句和子查詢。我可以採取另一種方法來提高性能嗎?此更新語句是存儲過程的一部分。改進此SQL查詢以獲得更好的性能

UPDATE dbo.CMN_PersonsFerpa 
    SET 
     IsWorkEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Work' THEN @IsFERPA ELSE IsWorkEmailFerpa END, 
     IsPersonalEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Personal' THEN @IsFERPA ELSE IsPersonalEmailFerpa END, 
     IsParentEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Parent' THEN @IsFERPA ELSE IsParentEmailFerpa END, 
     IsTempEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Temporary' THEN @IsFERPA ELSE IsTempEmailFerpa END, 
     IsFAFSAEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'FAFSA' THEN @IsFERPA ELSE IsFAFSAEmailFerpa END, 
     IsCSSProfEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'CSS Profile' THEN @IsFERPA ELSE IsCSSProfEmailFerpa END, 
     IsCommenceEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Commencement' THEN @IsFERPA ELSE IsCommenceEmailFerpa END, 
     IsAcctHoldEmailFerpa = (CASE WHEN (SELECT EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) = 'Account Holder' THEN @IsFERPA ELSE IsAcctHoldEmailFerpa END 
    Where CMN_PersonsFerpa.cmn_personsID = (select cmn_personsID from CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) 

在這裏有幾個建議是我有。這可以接受嗎?還是有更好的辦法?:

SELECT @DBType = EmailType, @cmn_personsID = CMN_PersonsID FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID 

    UPDATE dbo.CMN_PersonsFerpa 
    SET 
     IsWorkEmailFerpa = CASE WHEN @DBType = 'Work' THEN @IsFERPA END, 
     IsPersonalEmailFerpa = CASE WHEN @DBType = 'Personal' THEN @IsFERPA END, 
     IsParentEmailFerpa = CASE WHEN @DBType = 'Parent' THEN @IsFERPA END, 
     IsTempEmailFerpa = CASE WHEN @DBType = 'Temporary' THEN @IsFERPA END, 
     IsFAFSAEmailFerpa = CASE WHEN @DBType = 'FAFSA' THEN @IsFERPA END, 
     IsCSSProfEmailFerpa = CASE WHEN @DBType = 'CSS Profile' THEN @IsFERPA END, 
     IsCommenceEmailFerpa = CASE WHEN @DBType = 'Commencement' THEN @IsFERPA END, 
     IsAcctHoldEmailFerpa = CASE WHEN @DBType = 'Account Holder' THEN @IsFERPA END, 
     LastChangeBy = @UserGUID, 
     LastChangeDateTime = GETDATE() 
      Where CMN_PersonsFerpa.cmn_personsID = @CMN_PersonsID 
+0

@CMN_PersonsEmailLinksID從哪裏來?它是否從CMN_PersonsFerpa中拉出來? – Malk 2014-09-24 21:00:38

+0

@CMN_PersonsEmailLinksID來自前端而不是任何表。 – NonProgrammer 2014-09-24 21:04:58

回答

2

目標是消除子查詢。您可以通過在更新之前構建臨時表或使用適當的鏈接來完成此操作。不知道你的數據模式很難幫你設計一些東西,但這裏是一個鏡頭:

update p set 
    IsWorkEmailFerpa = case when e.EmailType = 'Work' then @IsFERPA else IsWorkEmailFerpa end, 
    IsPersonalEmailFerpa = case when e.EmailType = 'Personal' then @IsFERPA else IsPersonalEmailFerpa end, 
    IsParentEmailFerpa = case when e.EmailType = 'Parent' then @IsFERPA else IsParentEmailFerpa end, 
    IsTempEmailFerpa = case when e.EmailType = 'Temporary' then @IsFERPA else IsTempEmailFerpa end, 
    ... 
    IsAcctHoldEmailFerpa = case when e.EmailType = 'Account Holder' then @IsFERPA else IsAcctHoldEmailFerpa end, 
from dbo.CMN_PersonsFerpa p 
    join dbo.CMN_PersonsEmailLinks e 
     on e.cmn_personsID = p.cmn_personsID 
where e.CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID 
0

而不是運行查詢8次,運行它一旦進入一個變量,該變量本身的執行情況。

會是這個樣子:

SELECT @EmailType = EmailType FROM dbo.CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID 

UPDATE dbo.CMN_PersonsFerpa 
    SET 
     IsWorkEmailFerpa = (CASE WHEN @EmailType = 'Work' THEN @IsFERPA ELSE IsWorkEmailFerpa END, 
     IsPersonalEmailFerpa = (CASE WHEN @EmailType = 'Personal' THEN @IsFERPA ELSE IsPersonalEmailFerpa END, 
     IsParentEmailFerpa = (CASE WHEN @EmailType = 'Parent' THEN @IsFERPA ELSE IsParentEmailFerpa END, 
     IsTempEmailFerpa = (CASE WHEN @EmailType = 'Temporary' THEN @IsFERPA ELSE IsTempEmailFerpa END, 
     IsFAFSAEmailFerpa = (CASE WHEN @EmailType = 'FAFSA' THEN @IsFERPA ELSE IsFAFSAEmailFerpa END, 
     IsCSSProfEmailFerpa = (CASE WHEN @EmailType = 'CSS Profile' THEN @IsFERPA ELSE IsCSSProfEmailFerpa END, 
     IsCommenceEmailFerpa = (CASE WHEN @EmailType = 'Commencement' THEN @IsFERPA ELSE IsCommenceEmailFerpa END, 
     IsAcctHoldEmailFerpa = (CASE WHEN @EmailType = 'Account Holder' THEN @IsFERPA ELSE IsAcctHoldEmailFerpa END 
    Where CMN_PersonsFerpa.cmn_personsID = (select cmn_personsID from CMN_PersonsEmailLinks WHERE CMN_PersonsEmailLinksID = @CMN_PersonsEmailLinksID) 
+0

-1如果EmailType在SELECT之後但UPDATE之前更改,會怎麼樣? – Anon 2014-09-24 22:06:33

1

你爲什麼不使用連接?相關的子查詢像光標一樣一行一行地工作,幾乎從不應該使用。