0

我相信有很多与此错误相关的 StackOverflow 帖子,但似乎没有一个有我正在寻找的简单解决方案。如果你们中的任何人能调查一下,我将不胜感激。

问题:我正在使用一个动态 sql 存储过程,它在 cte 表达式中使用 FundTransfer 数据库表,然后与 WebbnkDb 数据库连接。

但是,我遇到了上面标题中提到的异常。如果我删除WITH EXECUTE AS SELF命令一切正常,但不幸的是我无法摆脱它,因为它用于某些安全原因。请用简单的话建议我解决方案。

USE [WebBank]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[usp_naSearchV2_20131504]   
@Debug    BIT = 0,   
@UserName   varchar(50)=NULL,   --This will be used to potentially limit the results per user & also for logging  
@SSN    char(9) = NULL,   
@FName    varchar(25) = NULL,   
@LName    varchar(30) = NULL, 
@dtApplicationStart datetime = NULL,  
@dtApplicationEnd datetime = NULL,  
@CompanyName  varchar(50) = NULL,  
@DaysInTask   int = NULL,   --This will be how many days it's been in the current task...  
@AcctNum   varchar(11) = NULL,  
@BranchNums   varchar(1500) = NULL, --This will be passed to an IN.  Don't enclose each in single quotes - for example, '45, 145, 1, 15'  
@WorkflowID   int = NULL,   --1 = HSA, 2 = Personal, 3 = SEI
@OriginationID  tinyint = NULL,   --This comes from the Applicant record.  
@QueueID   int = NULL,      
@TaskStageIDs  varchar(500) = NULL, --Will be passed to an IN, so multiple TaskStageIDs can be passed.              
@TaskIDs VARCHAR(1500)=NULL,  
@DaysAged   int = NULL,   --Days since application was entered  (not including time spent in approved/declined/open states)              
@LastActivityStart datetime=NULL,              
@LastActivityEnd datetime=NULL, 
@SOAApplID   int = NULL,   --SEI ID  
@Market VARCHAR(50) = NULL,   --from luAffinityMarket               
@IncludeSecondary bit=0,  
@IncludeAliasName bit=0,               
@EmailTypeIDs varchar(500) = NULL

WITH EXECUTE AS SELF --This is needed because we're using dynamic SQL & don't want to grant access to underlying tables.  
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

/*               
** New Account - Search.
**  
** This will be done in dynamic SQL.  The reason is because when searching on multiple optional parameters,
** SQL cannot use indexes without using dynamic SQL.  This makes the proc sssssslllllooooooooowwwwwwwwwww (when not using dynamic sql).
** See http://www.sommarskog.se/dyn-search-2005.html
** 
** In addition to the basics (name, social, branch, product, "workflow"), also show Task, Queue, Check-Out info, etc
** 
*/               

/*              
I have to create new version of this store procedure since we continue making changes to resolve helpdesk tickets and               
for AOT Part 2. Some tables that we are going to use for AOT project part 2 will not be moved to production until 12/05/10.              
New version will be called usp_naSearchV2 and will contain new tables for AOT Part 2                
*/ 

--CAST(ROUND(ISNULL(cteAge.Age + 1, 0), 2) AS DECIMAL(8, 2)) AS DaysAged,
DECLARE @SQL  nvarchar(max),@paramlist nvarchar(max)   
DECLARE @SOASQL nvarchar(MAX)     

SET @FName = '%' + @FName + '%'
SET @LName = '%' + @LName + '%'  
SET @CompanyName = '%' + @CompanyName + '%'  

SELECT @SQL = '  
WITH 
cteAutoApprove (AcctID, AutoApproved)
AS (
SELECT awt.AcctID, MIN(CAST(awt.autoEnter AS SMALLINT)) AS AutoApproved
FROM dbo.AccountWorkflowTask awt JOIN dbo.WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID
WHERE (wt.TaskID IN (9, 17) AND ReasonIDExit = 1)
OR (wt.TaskID IN (209, 309, 409, 509, 609, 709, 809, 909) AND ReasonIDExit = 40)
--OR ReasonIDExit IN(216,202) OR ReasonIDEnter=215
or(wt.TaskID=201 and ReasonIDExit is NULL) GROUP BY awt.AcctID),
cteAge (AcctID, Age)
AS (SELECT AcctID, SUM(CASE WHEN t.TaskStageID IN (2, 3, 4) OR t.TaskID = 1 THEN 0 '--don''t count Pending Completion, Open, Approved, or Declined in age
+ 'ELSE DATEDIFF(minute, dtEnter, ISNULL(dtExit, GETDATE())) END) / 60 / 24.0 Age
FROM dbo.AccountWorkflowTask awt JOIN WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID           JOIN Task t ON wt.TaskID = t.TaskID
GROUP BY AcctID),  
**cteFundingStatus(AcctID,FundingStatus,SourceAccountTypeDescription)
AS
(SELECT TransferStaging.AcctID,luTransferStatus.TransferStatusDesc, luAcctType.AcctTypeDesc  from 
FundsTransfer.dbo.TransferStaging 
JOIN FundsTransfer.dbo.luTransferType ON  luTransferType.TransferTypeID = TransferStaging.TransferTypeID    
JOIN FundsTransfer.dbo.luAcctType ON luTransferType.SourceAcctTypeID = luAcctType.AcctTypeID      
JOIN FundsTransfer.dbo.luTransferStatus ON luTransferStatus.TransferStatusID = TransferStaging.TransferStatusID),**                
cteFulfillment(AcctID, Request, TemplateName)
AS
(SELECT ful.AcctID, CAST(Request AS NVARCHAR(max))Request, lt.TemplateName  FROM dbo.fulfillment ful left join LetterRequest lr on lr.LetterID = ful.LetterID  
LEFT JOIN luLetterTemplate lt ON lt.TemplateID = lr.TemplateID  
WHERE (Request IS NOT NULL OR ful.LetterID IS NOT NULL) AND FulfillmentID=(SELECT MAX(FulfillmentID) FROM fulfillment  sub WHERE ful.AcctID=sub.AcctID AND (Request IS NOT NULL OR LetterID IS NOT NULL))  ),              
cteNote(AcctID,userEntered,dtEntered,Note,NoteReasonDesc,ReasonCode,NoteReasonID)              
as              
(SELECT AcctID,userEntered,dtEntered,Note,NoteReasonDesc,ReasonCode,n.NoteReasonID FROM note n JOIN              
dbo.luNoteReason lu ON lu.NoteReasonID=n.NoteReasonID WHERE '  

IF @EmailTypeIDs IS NOT NULL                
SELECT @SQL=@SQL+'  n.NoteReasonID IN (' + @EmailTypeIDs + ') AND '    

SELECT @SQL=@SQL+ ' dtEntered=(SELECT MAX(dtEntered)FROM note sub WHERE sub.AcctId=n.AcctID '  

IF @EmailTypeIDs IS NOT NULL                
SELECT @SQL=@SQL+ ' AND sub.NoteReasonID IN (' + @EmailTypeIDs + ')'  

SELECT @SQL=@SQL+')) '    

SELECT @SQL=@SQL+'SELECT a.ApplID, acct.AcctID, acct.dtApplication, ai.FName, ai.MName, ai.LName, ai.SSN, a.Email, ao.CompanyName,'
SELECT @SQL=@SQL+'ao.DBAName, ao.TaxID, acct.AcctNum, acct.AcctAffinityNum, luA.AffinityNum, luA.AffinityName, t.TaskDesc, awt.dtEnter,'
SELECT @SQL=@SQL+'DATEDIFF(day, awt.dtEnter, GETDATE()) + 1 DaysInTask, q.QueueDesc, w.WorkflowID, w.WorkflowDesc,'
SELECT @SQL=@SQL+'luO.OriginationID, luO.OriginationDesc, aco.dtCheckOut, aco.UserCheckOut, aco.GUIDCheckout, lts.TaskStageDesc,'
SELECT @SQL=@SQL+'DATEDIFF(day, acct.dtApplication, GETDATE()) + 1 DaysAgedOld,CAST(ROUND(ISNULL(cteAge.Age + 1, 0), 2) AS int) AS DaysAged,' 
SELECT @SQL=@SQL+'asa.SOAApplID, case when (w.WorkflowID=1 and luO.OriginationID=4) then ''Low''when  luO.OriginationID=9 then ''Low'''                 
SELECT @SQL=@SQL+'else''High'' end as RiskType, awt.userEnter, awt.dtEnter, case when cteAutoApprove.AutoApproved=1 then ''Automated'''              
SELECT @SQL=@SQL+'when cteAutoApprove.AutoApproved=0 then ''Manual'' else '''' end as DecisionType,acctLam.Market,ful.Request,ful.TemplateName,fun.SourceAccountTypeDescription,fun.FundingStatus, acct.BrokerCode,              
COALESCE(ai.SSN, ao.TAXID) as TIN, case when bup.BusPurposeDesc like ''%Other%'' then ao.BusPurposeOther else bup.BusPurposeDesc end as BusPurpose           
,note.Note,note.NoteReasonDesc,note.ReasonCode,aa.RelationshipCode,luRel.RelationshipCodeDesc, Addr.Address1, Addr.Address2, Addr.City, Addr.State, Addr.Zip FROM   dbo.Applicant a JOIN dbo.APPLICANTACCOUNT aa ON a.ApplID = aa.ApplID '              

IF @IncludeSecondary=0               
SELECT @SQL=@SQL+' AND aa.RelationshipCode = ''000'' '

SELECT @SQL=@SQL+'LEFT JOIN dbo.ApplicantIndiv ai ON a.ApplID = ai.ApplID  LEFT JOIN dbo.ApplicantOrg ao ON a.ApplID = ao.ApplID JOIN dbo.AFFINITYGROUP ag ON a.AffGroupID = ag.AffGroupID JOIN dbo.luAffinity luA ON ag.AffinityID = luA.AffinityID          

JOIN dbo.Account acct ON aa.AcctID = acct.AcctID JOIN dbo.AccountWorkflowTask awt ON acct.AcctID = awt.AcctID AND awt.dtExit IS NULL --join to current AccountWorkflowTask 
JOIN dbo.WorkflowTask wt ON awt.WorkflowTaskID = wt.WorkflowTaskID JOIN dbo.Task t ON wt.TaskID = t.TaskID 
JOIN dbo.Workflow w ON wt.WorkflowID = w.WorkflowID JOIN dbo.luTaskStage lts ON t.TaskStageID = lts.TaskStageID
LEFT JOIN dbo.Queue q ON t.QueueID = q.QueueID LEFT JOIN dbo.luOrigination luO on a.OriginationID = luO.OriginationID 
LEFT JOIN dbo.accountCheckOut aco ON acct.AcctID = aco.AcctID AND aco.dtCheckIn IS NULL LEFT JOIN AccountSOAApplication asa ON acct.AcctID = asa.AcctID
LEFT JOIN cteAutoApprove on cteAutoApprove.AcctID = acct.AcctID LEFT JOIN cteAge ON cteAge.AcctID = acct.AcctID 
LEFT JOIN luAffinityMarket lam ON CAST(luA.AffinityNum AS INT) = CAST(lam.BRNCH_NBR AS INT) LEFT JOIN luAffinityMarket acctLam ON acct.AcctAffinityNum = CAST(acctLam.BRNCH_NBR AS INT) 
LEFT JOIN cteFulfillment ful on acct.AcctID=ful.AcctID 
left Join **cteFundingStatus** fun on  fun.AcctID=acct.AcctID               
left Join luBusPurpose bup on bup.BusPurposeID=ao.BusPurposeID               
Left join cteNote note on acct.AcctID=note.AcctID              
left join luRelationshipCode luRel on aa.RelationshipCode=luRel.RelationshipCode   
LEFT JOIN Address Addr ON Addr.ApplID = aa.ApplID AND Addr.AddrTypeID = 1  
WHERE  1 = 1 ' --this is in here so that the following statements in the WHERE clause can start with "AND (...)". 
-- IF @debug = 1 PRINT LEN(@SQL)  v_AOTInitialAccountFunding                
--SELECT @SQL = REPLACE(@SQL, CHAR(9), '') --remove tabs to save string size
IF @debug = 1 PRINT LEN(@SQL)

IF @SSN IS NOT NULL 
SELECT @sql = @sql + ' AND (ai.SSN = @xSSN OR REPLACE(ao.TaxID, ''-'', '''') = @xSSN)'     
IF @IncludeAliasName  <>1 AND @FName IS NOT NULL     
SELECT @sql = @sql + ' AND (ai.FName LIKE @xFName)'     
IF @IncludeAliasName  <>1 AND @LName IS NOT NULL     
SELECT @sql = @sql + ' AND (ai.LName LIKE @xLName)'   
IF @IncludeAliasName  <>0 AND @FName IS NOT NULL  
SELECT @sql = @sql + ' AND (ai.AliasFName LIKE @xFName OR ai.FName LIKE @xFName)'     
IF @IncludeAliasName  <>0 AND @LName IS NOT NULL     
SELECT @sql = @sql + ' AND (ai.AliasLName LIKE @xLName OR ai.LName LIKE @xLName)'     
IF @dtApplicationStart IS NOT NULL     
SELECT @sql = @sql + ' AND (CONVERT(char(10), acct.dtApplication, 101) >= @xdtApplicationStart)'     
IF @dtApplicationEnd IS NOT NULL     
SELECT @sql = @sql + ' AND (CONVERT(char(10), acct.dtApplication, 101) <= @xdtApplicationEnd)'     
IF @CompanyName IS NOT NULL  
SELECT @sql = @sql + ' AND (ao.CompanyName LIKE @xCompanyName)'     
IF @DaysInTask IS NOT NULL  
SELECT @sql = @sql + ' AND (DATEDIFF(day, awt.dtEnter, GETDATE()) >= @xDaysInTask)'   
IF @AcctNum IS NOT NULL  
SELECT @sql = @sql + ' AND (acct.AcctNum LIKE @xAcctNum)'  
IF @BranchNums IS NOT NULL  
--Can't use a parameter of the executesql for the list of affinity numbers.  
SELECT @sql = @sql + ' AND (acct.AcctAffinityNum IN (' + @BranchNums + ') OR luA.AffinityNum IN (' + @BranchNums + '))'  
IF @WorkflowID IS NOT NULL  
SELECT @sql = @sql + ' AND (w.WorkflowID = @xWorkflowID)'  
IF @OriginationID IS NOT NULL  
SELECT @sql = @sql + ' AND (a.OriginationID = @xOriginationID)'  
IF @QueueID IS NOT NULL  
SELECT @sql = @sql + ' AND (t.QueueID = @xQueueID)'  
IF @TaskStageIDs IS NOT NULL  
--Can't use a parameter of the executesql for the list of affinity numbers.  
SELECT @sql = @sql + ' AND (lts.TaskStageID IN (' + @TaskStageIDs + '))'               
IF @TaskIDs IS NOT NULL  
--Can't use a parameter of the executesql for the list of affinity numbers.  
SELECT @sql = @sql + ' AND (t.TaskID IN (' + @TaskIDs + '))'  
IF @DaysAged IS NOT NULL
SELECT @sql = @sql + ' AND ISNULL(cteAge.Age + 1, 0)  <= @xDaysAged'   
--SELECT @sql = @sql + ' AND (DATEDIFF(day, acct.dtApplication, GETDATE()) + 1 = @xDaysAged)'              
IF @LastActivityStart IS NOT NULL              
SELECT @sql = @sql + ' AND (CONVERT(char(10), awt.dtEnter, 101) >= @xLastActivityStart)'              
IF @LastActivityEnd IS NOT NULL              
SELECT @sql = @sql + ' AND (CONVERT(char(10), awt.dtEnter, 101) <= @xLastActivityEnd)'
IF @Market IS NOT NULL
SELECT @sql = @sql + ' AND (lam.Market = @xMarket OR acctLam.Market = @xMarket)'              
IF @EmailTypeIDs IS NOT NULL
SELECT @sql = @sql + ' AND (note.NoteReasonID IN (' + @EmailTypeIDs + '))' 
IF @SOAApplID IS NOT NULL   
SELECT @sql = @sql + ' AND asa.SOAApplID = @xSOAApplID UNION               
SELECT NULL ApplID, NULL AcctID, sa.dtAdded dtApplication, sap.FName, sap.MName, sap.LName, sap.SSN, sap.Email, NULL CompanyName,NULL DBAName,   
NULL TaxID, NULL AcctNum, 145 AcctAffinityNum, ''145'' AffinityNum, luA.AffinityName, NULL TaskDesc, NULL dtEnter,
NULL DaysInTask, NULL QueueDesc, NULL WorkflowID, ''SEI Online App''  WorkflowDesc,NULL OriginationID, NULL OriginationDesc, NULL dtCheckOut,   
NULL UserCheckOut, NULL GUIDCheckout, NULL TaskStageDesc, 
0, DATEDIFF(day, sa.dtAdded, GETDATE()) + 1 DaysAged, sa.SOAApplID,'' '',  '' '', '' '' dtEnter,  '' ''DecisionType,'' '' Market,  
'' ''Request,'' ''SourceAccountTypeDescription,'' ''FundingStatus,'' ''BrokerCode, '' ''TIN,'' ''BusPurpose,'' ''Note,'' ''t,  
'' ''t1,'' '' RelationshipCode, '' '' RelationshipCodeDesc  FROM SOAApplication sa LEFT JOIN AccountSOAApplication asa   
ON sa.SOAApplID = asa.SOAApplID  JOIN SOAApplicant sap ON sa.SOAApplID = sap.SOAApplID JOIN luAffinity luA ON luA.AffinityNum = ''145''   
WHERE asa.SOAApplID IS NULL AND sa.SOAApplID = @xSOAApplID AND sap.PrimaryContact = 1' 

IF @debug = 1
PRINT @sql

IF @debug = 1
PRINT @sql

SELECT @paramlist = 
'@xSSN    char(9),
@xFName   varchar(25),
@xLName   varchar(30),
@xdtApplicationStart datetime,
@xdtApplicationEnd  datetime,
@xCompanyName  varchar(50),
@xDaysInTask  int,
@xAcctNum   varchar(11),
@xWorkflowID  int,
@xOriginationID tinyint,
@xQueueID   int,
@xDaysAged  int,
@xMarket   varchar(50),
@xSOAApplID  int,  
@xLastActivityStart datetime,
@xLastActivityEnd datetime'

IF @Debug = 1 PRINT LEN(@SQL)

EXEC sp_executesql @sql, @paramlist,
@SSN,
@FName,
@LName,
@dtApplicationStart,
@dtApplicationEnd,
@CompanyName,
@DaysInTask,
@AcctNum,
@WorkflowID,
@OriginationID,  
@QueueID,  
@DaysAged,
@Market,
@SOAApplID,
@LastActivityStart,
@LastActivityEnd
4

1 回答 1

2

因此,当您将EXECUTE AS SELF添加到过程中时,就相当于说“执行此过程,就好像创建它的人正在运行它一样”。因此,无论谁部署该程序(在任何主要帐户下),都将成为该程序使用的基础。

我假设您的部署策略是让管理员使用 sa 帐户运行 CREATE/ALTER 步骤。您的 DBA 可能遵循最佳实践并且没有 sa 帐户拥有服务器上的数据库(并且可能根本没有读取访问权限),因此您会收到安全错误。

鉴于所有这些,在您目前的情况下,您可能不会使用EXECUTE AS SELF,或者至少我怀疑是这样。就您何时希望在更一般的意义上使用它而言,很难给出一个笼统的答案。简短版本是,如果您(“您”是可以登录的主体)需要以的权限级别运行对象,而不是调用者拥有的任何权限。

于 2013-04-17T19:58:08.323 回答