我编写了脚本来对表中的值进行一些修复。但它需要永远完成..实际上从来没有看到它完成..只是挂在那里..任何点如何优化它将不胜感激。
有两个表: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;
答案 0 :(得分:1)
我不认为很多人会读那么长的查询。逻辑是多余的。
例如if(select count(something)= 0)你可以用having子句替换并消除嵌套游标的额外使用。
以下代码仅供参考。在代码中有条款之前我没有把'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;
答案 1 :(得分:1)
你真的需要在每个循环中(通常在循环的end
之前)放入它们的关联fetch from...
指令,与每个循环之前的指令相同。