2011-03-04 72 views
0

我寫了腳本來爲表中的值做一些修復。但它需要永遠完成..實際上從來沒有看到它完成..只是掛在那裏..任何一點如何優化,將不勝感激。如何讓這個SQL腳本運行得更快?

有兩個表格:FundCorrespondencePreference其中可以有一些在記錄中檢查的IDContacts列。如果他們被選中,那麼相應的記錄應該存在於ContentManagementRights表中(除了一些字段外,幾乎相同的字段)。

的想法是要經過ContentManagemtnRights並找到所有結合 4列獨特的記錄,挑了一些列的值,並從FundCorrespondencePreference table收集所有的用戶,然後檢查,如果該用戶是集合中籤, 去回到ContentManagementRights表並檢查是否存在這樣的記錄,如果不存在,則在列中插入具有相應值的記錄。

希望我或多或少地一致解釋。任何方式,感謝您的時間和建議。這裏去腳本:

--the script will check if any of the contacts for a partner in FundCorrespondencePreferences are missing in ContentManagementRight table 
-- some of the contacts in FundCorrespondencePreference just not appear in ContentManagementRight as checked 

    declare @IDFundInfo char(30) 
    declare @IDCompany char(30) 
    declare @IDFundTransactionParameter char(30) 
    declare @IDContentManagement char(30) 
    declare @IDUserInfo char(30) 
    declare @ID char(30) 

    declare @curContentManagementRights cursor 
    set @curContentManagementRights = cursor fast_forward for 
    --first select distinct records from ContentManagementRights for IDFundInfo, IDCompany,IDFundTransactionParameter and IDContentManagement where 
    --bFundLevelAccess == 0 
    SELECT distinct 
     ContentManagementRights.IDFundInfo, 
     ContentManagementRights.IDCompany, 
     ContentManagementRights.IDFundTransactionParameter, 
     ContentManagementRights.IDContentManagement 
    FROM ContentManagementRights 
    WHERE  
     (ContentManagementRights.bFundLevelAccess = 0) 
    ORDER BY 
     idfundinfo, idcompany,idfundtransactionparameter, idcontentmanagement 

    open @curContentManagementRights; 
    fetch from @curContentManagementRights into @IDFundInfo, @IDCompany,@IDFundTransactionParameter,@IDContentManagement 

    WHKLE @@fetch_status = 0 
    BEGIN 
     --get all IDContactInfo for the chosen fund, partnerid,fundtranactionparameterid from fundcorrespondencepreference table + make sure that at least one correspTO parameter 

     declare @curFundCorrespondencePreference cursor 
     set @curFundCorrespondencePreference = cursor fast_forward for 
     SELECT  
      UserInfo.IDUserInfo 
     FROM   
      FundCorrespondencePreference 
     INNER JOIN 
      FundTransactionParameter ON FundCorrespondencePreference.IDFundTransactionParameter = FundTransactionParameter.IDFundTransactionParameter 
     INNER JOIN 
      ContactInfo ON FundCorrespondencePreference.IDContactInfo = ContactInfo.IDContactInfo 
     INNER JOIN 
      UserInfo ON ContactInfo.IDContactInfo = UserInfo.IDContactInfo 
     INNER JOIN 
      UserGroupInfo ON UserInfo.IDUserInfo = UserGroupInfo.IDUserInfo 
     INNER JOIN 
      GroupInfo ON UserGroupInfo.IDGroupInfo = GroupInfo.IDGroupInfo 
     WHERE  
      (FundTransactionParameter.IDFundInfo = @IDFundInfo) 
      AND (FundCorrespondencePreference.IDCompany = @IDCompany) 
      AND (FundCorrespondencePreference.IDFundTransactionParameter = @IDFundTransactionParameter) 
      AND (FundCorrespondencePreference.bEmail = 1) 
      AND (GroupInfo.sName = N'Xtranet Partner Group') 
      OR (FundCorrespondencePreference.bFax = 1) 
      OR (FundCorrespondencePreference.bLetterTo = 1) 
      OR (FundCorrespondencePreference.bLetterCc = 1) 
      OR (FundCorrespondencePreference.bEmailCc = 1) 
      OR (FundCorrespondencePreference.bFaxCc = 1) 

      --go through all the contacts chosen from FundCorrespondencePreference table and 
      --if not present in ContentManagementRight table, insert into the table record with previously selected parameters 
      open @curFundCorrespondencePreference; 
      fetch from @curFundCorrespondencePreference into @IDUserInfo 

      WHILE @@fetch_status = 0 
      BEGIN 
      if 
       (Select Count(IDContentManagementRights) 
       from ContentManagementRights 
       where 
        IDContentManagement = @IDContentManagement 
        and IDFundInfo = @IDFundInfo 
        and IDCompany = @IDCompany 
        and IDUserInfo = @IDUserInfo) = 0 
      begin 
      --insert a new record in ContentManagementRights if there is none for chosen parameters 
      Exec GetNextID 'ContentManagementRights', @ID output 
      INSERT INTO ContentManagementRights (IDContentManagementRights,IDContentManagement,IDFundInfo,IDCompany,sCreatedBy,dtCreatedDate,sUpdatedBy,dtUpdatedDate,IDUserInfo,IDFundTransactionParameter,bFundLevelAccess) 
      VALUES (@ID,@IDContentManagement,@IDFundInfo,@IDCompany,'admin',GETDATE(),'admin',GETDATE(),@IDUserInfo,@IDFundTransactionParameter,0)   
       end 
     end 
     close @curFundCorrespondencePreference; 
     deallocate @curFundCorrespondencePreference; 
    --  
     end 

    close @curContentManagementRights; 
    deallocate @curContentManagementRights; 
+4

那麼,用**兩個嵌套遊標**,這是難怪它需要永遠....我的建議是這樣的:嘗試創建一個單一的查詢,與SELECT,JOIN等,給你的名單你想插入的行。不要以程序思考 - 想想成組的行,想想數據之間的關係。如果你可以創建它,它會快得多 – 2011-03-04 06:03:08

+0

@marc_s我同意..將嘗試創建一個巨大的:) .. sql語句.. – HotFrost 2011-03-04 16:05:10

+0

我明白你爲什麼使用遊標。你有一個「Sequence」表,你使用GetNextID proc來獲得ID。如果您可以發佈GetNextID proc的代碼,我可能會向您展示解決單個ID返回問題的方法。我也會仔細檢查你的代碼,因爲這樣的過程通常是一個巨大的死鎖源。 – 2011-03-07 03:58:34

回答

1

我不認爲很多人會讀取很長的查詢。邏輯是多餘的。

例如,如果(select count(something)= 0)u可以替換爲有子句並且消除額外使用嵌套遊標。

下面的代碼只是指導。在代碼中添加子句之前,我沒有將'group by'放在一起。希望能幫助到你。

我的提示是,SQL是製作數據操縱語言的。不是像OOP編程那樣的個人對象。我說這是因爲你嘗試使用光標來處理每一行,這是OOP編程風格,例如。 for循環在每一行中進行工作。 但SQL意圖一次在多行上工作。嘗試使用聚合,情況時,而不是

declare @IDFundInfo char(30) 
    declare @IDCompany char(30) 
    declare @IDFundTransactionParameter char(30) 
    declare @IDContentManagement char(30) 
    declare @IDUserInfo char(30) 
    declare @ID char(30) 

    declare @curContentManagementRights cursor 
    set @curContentManagementRights = cursor fast_forward for 
    --first select distinct records from ContentManagementRights for IDFundInfo, IDCompany,IDFundTransactionParameter and IDContentManagement where 
    --bFundLevelAccess == 0 
    SELECT distinct 
     ContentManagementRights.IDFundInfo, 
     ContentManagementRights.IDCompany, 
     ContentManagementRights.IDFundTransactionParameter, 
     ContentManagementRights.IDContentManagement 
    FROM ContentManagementRights 
    WHERE  
     (ContentManagementRights.bFundLevelAccess = 0) 
    ORDER BY 
     idfundinfo, idcompany,idfundtransactionparameter, idcontentmanagement 

    open @curContentManagementRights; 
    fetch from @curContentManagementRights into @IDFundInfo, @IDCompany,@IDFundTransactionParameter,@IDContentManagement 

    WHKLE @@fetch_status = 0 
    BEGIN 
     --get all IDContactInfo for the chosen fund, partnerid,fundtranactionparameterid from fundcorrespondencepreference table + make sure that at least one correspTO parameter 

    INSERT INTO ContentManagementRights (IDContentManagementRights,IDContentManagement,IDFundInfo,IDCompany,sCreatedBy,dtCreatedDate,sUpdatedBy,dtUpdatedDate,IDUserInfo,IDFundTransactionParameter,bFundLevelAccess) 
     SELECT  
      @ID,@IDContentManagement,@IDFundInfo,@IDCompany,'admin',GETDATE(),'admin',GETDATE(),UserInfo.IDUserInfo,@IDFundTransactionParameter,0 
     FROM   
      FundCorrespondencePreference 
     INNER JOIN 
      FundTransactionParameter ON FundCorrespondencePreference.IDFundTransactionParameter = FundTransactionParameter.IDFundTransactionParameter 
     INNER JOIN 
      ContactInfo ON FundCorrespondencePreference.IDContactInfo = ContactInfo.IDContactInfo 
     INNER JOIN 
      UserInfo ON ContactInfo.IDContactInfo = UserInfo.IDContactInfo 
     INNER JOIN 
      UserGroupInfo ON UserInfo.IDUserInfo = UserGroupInfo.IDUserInfo 
     INNER JOIN 
      GroupInfo ON UserGroupInfo.IDGroupInfo = GroupInfo.IDGroupInfo 
     WHERE  
      (FundTransactionParameter.IDFundInfo = @IDFundInfo) 
      AND (FundCorrespondencePreference.IDCompany = @IDCompany) 
      AND (FundCorrespondencePreference.IDFundTransactionParameter = @IDFundTransactionParameter) 
      AND (FundCorrespondencePreference.bEmail = 1) 
      AND (GroupInfo.sName = N'Xtranet Partner Group') 
      OR (FundCorrespondencePreference.bFax = 1) 
      OR (FundCorrespondencePreference.bLetterTo = 1) 
      OR (FundCorrespondencePreference.bLetterCc = 1) 
      OR (FundCorrespondencePreference.bEmailCc = 1) 
      OR (FundCorrespondencePreference.bFaxCc = 1) 

    having count(IDContentManagementRights) = 0 

     end 

    close @curContentManagementRights; 
    deallocate @curContentManagementRights; 
+0

感謝Bonshington ..你是對的..一個人在使用sql時必須打開一個不同的心態..我仍然在OOP – HotFrost 2011-03-04 16:06:58

1

先生或女士,你做得很好,拒絕等到腳本完成其工作。這裏有兩個光標,沒有一個正在滾動到第一行之外。這個劇本確實需要永遠完成。 (好吧,只要該系統可保持工作,反正。)

你真的需要把每一個循環內(通常立即循環的end之前)的關聯fetch from...說明,相同的情況以前生產的循環。

+0

ha-ha .. @Andriy M - 一個slona ya我ne zametil ..: ) 你是對的..腳本丟失:從聲明中取下一個.. :) 謝謝! – HotFrost 2011-03-04 16:13:51

+0

@ user194033:那麼對你有好處。 :) – 2011-03-04 16:26:37

相關問題