Stored Procedure error "Must declare the scalar variable" - sql

I have written a stored procedure to extract data from a table in SQL Server:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[csp_OperatorVarianceMonthlyView]
-- =============================================
-- Procedure: csp_OperatorVarianceMonthlyView
--
-- Summary: Produce the result table that is needed for the Operator Variance Tracker report.
--
-- Params: #RetailStoreId - Store Id on which the results need to be filtered
-- #StartDate - The start business day date for which results are to be collected (NULL = Today)
-- #EndDate - The end business day date for which results are to be collected (NULL = Today)
-- #OperatorIDList - OperatorID comma seperated list
-- Returns: A result set to populate a Operator Variance Report tab
--
-- Version: 2013-06-25 11:00
-- ==============================================
#TenantID t_ID,
#RetailStoreID t_ID,
#StartDate t_Timestamp = null,
#EndDate t_Timestamp = null,
#OperatorIDList varchar(500)=null
AS
IF 1 = 0
BEGIN
SET FMTONLY OFF
END
BEGIN
declare #SQL nvarchar(2500)
declare #StartBusinessDayDate t_TimeStamp
declare #EndBusinessDayDate t_TimeStamp
declare #StartDateOfYear t_TimeStamp
declare #StartDateOfMonth t_TimeStamp
declare #Sunday t_TimeStamp
declare #FirstSundayOfMonth t_TimeStamp
SET NOCOUNT ON;
if (#StartDate is null)
select #StartDate = GETDATE()
if (#EndDate is null)
select #EndDate = GETDATE()
-- Eliminate any time information that might be in the Start/End dates
select #StartBusinessDayDate = convert(varchar(8), cast (#StartDate as datetime), 112)
select #EndBusinessDayDate = convert(varchar(8), cast (#EndDate as datetime), 112)
-- Compute StartDateOfYear and StartDateOfMonth to compute the YTD and MTD variances
set #StartDateOfYear = DATEADD(year, DATEDIFF(year, 0, #EndBusinessDayDate),0)
set #StartDateOfMonth = DATEADD(month, DATEDIFF(month, 0, #EndBusinessDayDate), 0)
-- Select a Sunday
set #Sunday = '2017-01-01'
-- Get first Sunday of the month for getting week-wise data for the OVT report
set #FirstSundayOfMonth = DATEADD(WEEK, DATEDIFF(WEEK, #Sunday, #StartBusinessDayDate), #Sunday)
-- Create temporary tables to hold the monthly and yearly variance amounts for each operator
Create table #TempOperatorVarianceYTD ([OperatorID] int, [VarianceAmtYTD] decimal)
Create table #TempOperatorVarianceMTD ([OperatorID] int, [VarianceAmtMTD] decimal)
-- Insert Year To Date (YTD) variance amounts by operator to the tempoarary table
Insert into #TempOperatorVarianceYTD
Select OperatorID, sum(NetOverShortAmount)
from TillBalanceExceptionPTDSummary
where BusinessDayDate between #StartDateOfYear and #EndBusinessDayDate
and RetailStoreID = #RetailStoreID
and PeriodTypeCode = 1
group by OperatorID
-- Insert Month To Date (MTD) variance amounts by operator to the tempoarary table
Insert into #TempOperatorVarianceMTD
Select OperatorID, sum(NetOverShortAmount)
from TillBalanceExceptionPTDSummary
where BusinessDayDate between #StartDateOfMonth and #EndBusinessDayDate
and RetailStoreID = #RetailStoreID
and PeriodTypeCode = 1
group by OperatorID
-- Build the SQL statement to get the result table for the monthly view of the Operator Variance Tracker report.
select #SQL = 'Select TBES.OperatorID as OperatorID, ' +
'O.[Name] as OperatorName, ' +
'YTD = YTD.VarianceAmtYTD, ' +
'MTD = MTD.VarianceAmtMTD, ' +
'Week1 = SUM(CASE WHEN TBES.PeriodTypeCode = 2 AND TBES.BusinessDayDate = #FirstSundayOfMonth THEN TBES.NetOverShortAmount ELSE 0 END), ' +
'Week2 = SUM(CASE WHEN TBES.PeriodTypeCode = 2 AND TBES.BusinessDayDate = DATEADD(WEEK, 1, #FirstSundayOfMonth) THEN TBES.NetOverShortAmount ELSE 0 END), ' +
'Week3 = SUM(CASE WHEN TBES.PeriodTypeCode = 2 AND TBES.BusinessDayDate = DATEADD(WEEK, 2, #FirstSundayOfMonth) THEN TBES.NetOverShortAmount ELSE 0 END), ' +
'Week4 = SUM(CASE WHEN TBES.PeriodTypeCode = 2 AND TBES.BusinessDayDate = DATEADD(WEEK, 3, #FirstSundayOfMonth) THEN TBES.NetOverShortAmount ELSE 0 END), ' +
'Week5 = SUM(CASE WHEN TBES.PeriodTypeCode = 2 AND TBES.BusinessDayDate = DATEADD(WEEK, 4, #FirstSundayOfMonth) THEN TBES.NetOverShortAmount ELSE 0 END) ' +
'FROM [postrn001].[dbo].[TillBalanceExceptionPTDSummary] TBES ' +
'join [posfdn001].[dbo].[Operator] O ' +
'on TBES.OperatorID = O.OperatorID ' +
'join #TempOperatorVarianceYTD YTD ' +
'on O.OperatorID = YTD.OperatorID ' +
'join #TempOperatorVarianceMTD MTD ' +
'on O.OperatorID = MTD.OperatorID ' +
'where TBES.RetailStoreID = #RetailStoreID '
-- Add the operator filter if necessary
if ( NOT (#OperatorIDList is null) )
begin
-- Avoid sql injection by cleaning the string
set #OperatorIDList = REPLACE(#OperatorIDList, ';', '')
set #OperatorIDList = REPLACE(#OperatorIDList, ')', '')
set #OperatorIDList = REPLACE(#OperatorIDList, '-', '')
select #SQL = #SQL + 'and TBES.OperatorID IN (' + #OperatorIDList + ') '
end
--Add the group by clause
select #SQL = #SQL + 'group by TBES.OperatorID, O.[Name], YTD.VarianceAmtYTD, MTD.VarianceAmtMTD'
print #SQL
print #FirstSundayOfMonth
exec sp_executesql #SQL,
N'#TenantID t_ID, #RetailStoreId t_ID, #StartBusinessDayDate t_TimeStamp, #EndBusinessDayDate t_TimeStamp, #OperatorIDList varchar(500)',
#TenantID, #RetailStoreId, #StartBusinessDayDate, #EndBusinessDayDate, #OperatorIDList
return ##error
-- Drop the temporary tables.
drop table #TempOperatorVarianceMTD, #TempOperatorVarianceYTD
END
Upon executing this, I get this error:
Must declare the scalar variable "#FirstSundayOfMonth"
As you can see in the code, I have declared and initialized the value of #FirstSundayOfMonth in the stored procedure.
I'm not sure on what I might be missing here - I tried copying the query part to a separate window and executing it after assigning the values to the declared variables and it executes and generates the result that I expect.
I'm guessing I'm missing something minor but I'm unable to figure out what it is.
Any leads on this would be great!

The variable declared in the outer scope is not visible to the dynamic SQL statement. Pass #FirstSundayOfMonth as another parameter to sp_executesql.

Related

How to pivot table by month and display top 10 by total amount only

I have a dynamic dataset that returns data from today and a year back.
How can I pivot this data and return only top 10 Description by NetWrittenPremium?
I know how to perform static pivot, but confused how would I do it in this case.
;with cte_TopClasses
AS (
SELECT
b.MonthNum,
b.YearNum,
GovClassCode + ' - ' + dda.GovClassDesc as Description,
ISNULL(SUM(Premium),0) as NetWrittenPremium
FROM tblCalendar b
LEFT JOIN ProductionReportMetrics prm ON b.YearNum = Year(prm.EffectiveDate) AND b.MonthNum=Month(prm.EffectiveDate) AND CompanyLine = 'Arch Insurance Company'
LEFT JOIN [dbo].[Dynamic_Data_ArchWC] dda ON prm.QuoteGUID = dda.QuoteGuid
WHERE
( b.YearNum = YEAR(GETDATE())-1 and b.MonthNum >= MONTH(GETDATE())+1 ) OR
( b.YearNum = YEAR(GETDATE()) and b.MonthNum <= MONTH(GETDATE()) )
GROUP BY b.YearNum ,
b.MonthNum,
GovClassCode,
dda.GovClassDesc
)
--here I want to pivot it
select *
from cte_TopClasses
Current result is 128 records.
And desirable result would be something like that:
#Nico
It should be like that:
Yours is very close, just shift to 1 month ahead.
Maybe it's somewhat complicated. More information about dynamic pivot, you can check this post.
--begin get the ordered month name of past one year
DECLARE #cols AS NVARCHAR(MAX)
DECLARE #startMonth AS INT
--line 1
SET #startMonth=MONTH(GETDATE())+1
WHILE(#startMonth<=12)
BEGIN
SET #cols= COALESCE(#cols,'')+'['+CAST(#startMonth AS varchar)+'],';
SET #startMonth=#startMonth+1;
END
--line 2
SET #startMonth=MONTH(GETDATE())+1
DECLARE #countFlag INT
SET #countFlag=0
WHILE(#startMonth>1)
BEGIN
SET #countFlag=#countFlag+1;
SET #cols= COALESCE(#cols,'')+'['+CAST(#countFlag AS varchar)+'],';
SET #startMonth=#startMonth-1;
END
SET #cols=SUBSTRING(#cols,1,LEN(#cols)-1)
-- end
DECLARE #query NVARCHAR(MAX)
SET #cols=REPLACE(#cols,'10','October');
SET #cols=REPLACE(#cols,'11','November');
SET #cols=REPLACE(#cols,'12','December');
SET #cols=REPLACE(#cols,'1','January');
SET #cols=REPLACE(#cols,'2','February');
SET #cols=REPLACE(#cols,'3','March');
SET #cols=REPLACE(#cols,'4','April');
SET #cols=REPLACE(#cols,'5','May');
SET #cols=REPLACE(#cols,'6','June');
SET #cols=REPLACE(#cols,'7','July');
SET #cols=REPLACE(#cols,'8','August');
SET #cols=REPLACE(#cols,'9','September');
SET #query = '
SELECT
TOP 10
*,
ISNULL([October],0)+ISNULL([November],0)+ISNULL([December],0)+ISNULL([January],0)+ISNULL([February],0)+ISNULL([March],0)+ISNULL([April],0)+ISNULL([May],0)+ISNULL([June],0)+ISNULL([July],0)+ISNULL([August],0)+ISNULL([September],0) AS Total
FROM
(
SELECT DateName(month, DateAdd(month, MonthNum, -1)) AS [MonthName],[Description],SUM(NetWrittenPremium) AS SubTotal FROM dbo.cte_TopClasses WHERE ((YearNum-YEAR(GETDATE()))*12+MonthNum-MONTH(GETDATE()))>-12 AND ((YearNum-YEAR(GETDATE()))*12+MonthNum-MONTH(GETDATE()))<=0 GROUP BY [MonthNum],[Description]
) AS source
PIVOT
(
SUM(SubTotal)
FOR MonthName
IN (' + #cols + ')
) AS pvtMonth
ORDER BY Total
'
EXEC SP_EXECUTESQL #query

While Loop Issue

Hoping that someone can offer some assistance, I am currently working on a piece of code which seems to be having issues. Unfortunately I cant post the underlying data but will try and explain.
The code currently cycles through a selection of kpi's and calculates if something needs to be run or not based on the current time and whether the individual kpi's need to be run. At the moment if I hard code a number of kpi's the code works fine but if I let it cycle through all the kpi's, ones that should not run are being told to run, also in the select that defines things like #Period, when I let it run through all KPI's its setting the #Period incorrectly when it shouldn't run but when its meant to run it set it fine.
Overall I have 2 issues which I think are related KPI's run when they are not meant to and when they are running when they are not meant to they pick up the wrong Period either way which is odd. I think what is happening is when I let it run all the way through the KPI's are getting mixed up but I cant see how this is happening, any help would be great before I go mad.
As you can see from my code there are 2 #current_timestamps, when its set to 23.45.18.873 it should not run some of the kpi's but it runs them all anyway and the 21.45.18.873 means that they can run.
declare #job_current_time_minute float,
#job_current_date_time_minute as datetime,
#current_timestamp as datetime
SET #job_current_time_minute = 52--cast(datepart(minute, getdate()) as float)
SET #job_current_date_time_minute = getdate()
--SET #current_timestamp = cast('2017-04-02 23:45:18.873' as datetime)
SET #current_timestamp = cast('2017-04-02 21:45:18.873' as datetime)
--Run: 88 6 0 52 5 5 5
--Run: 88 1 10 52 5 5 5
declare
#kpi_id int,
#kpi_parent_id int,
#sql nvarchar(max),
#kpi_last_result nvarchar(100),
#kpi_last_runtime datetime,
#kpi_params nvarchar(max),
#kpi_current_time_minute float,
#schedulue_minute float,
#reoccurrence float,
#result float,
#kpi2 int,
-- Email Variables
#kpi_name nvarchar(150),
#kpi_desc nvarchar(150),
#kpi_report_link nvarchar(150),
#kpi_email_subject nvarchar(150),
#kpi_email_body nvarchar(300),
#kpi_email_query nvarchar(max),
#kpi_sms_msg nvarchar(300);
SET #kpi_params = N'#retvalOUT varchar(max) OUTPUT';
select #kpi_id = min(kpi_id) from KPI where KPI_Active = 1; --and kpi_id in (86, 88)
while #kpi_id is not null
begin
select
#kpi_parent_id = kpi_parent_id,
#sql = kpi_Script,
#schedulue_minute = datepart(minute,s.Schedule_Start),
#reoccurrence = s.Reoccurrence,
#result = cast((#job_current_time_minute - datepart(minute,s.Schedule_Start)) / s.Reoccurrence as decimal(18,2)),
#kpi_name = kpi_name,
#kpi_desc = kpi_desc,
#kpi_report_link = kpi_report_link,
#kpi_email_subject = kpi_email_subject,
#kpi_email_body = kpi_email_body,
#kpi_email_query = kpi_email_query,
#kpi_sms_msg = kpi_sms_msg,
#kpi_current_time_minute = 60*DATEPART(HOUR, GETDATE())+DATEPART(MINUTE,GETDATE()),
#kpi2 = KPI_ID
from EWI..KPI
inner join EWI..Schedule s on KPI.Schedule_ID = s.Schedule_ID where kpi_id = #kpi_id--order by kpi_id asc
--set #sql = 'select #retvalOUT= (' + #sql + ')'
if floor(#result) <> ceiling(#result)
begin
PRINT 'Not Time to Run: ' + ' ' + cast(#kpi_id as varchar(11)) + ' ' + cast(#result as varchar(11))
end
else
begin
declare
#ThresholdID int,
#PeriodID int,
#Threshold_value int,
#Threshold_PosNeg nvarchar(5)
select #ThresholdID = Threshold_ID, #PeriodID = Period_ID, #Threshold_value = Threshold_value, #Threshold_PosNeg = Threshold_PosNeg from (
-- select * from (
select * from (
select KPI_ID, t.Threshold_ID, p.Period_ID, t.Threshold_Value, t.Threshold_PosNeg, p.DayStartTime, p.DayEndTime, Period_desc, [Day]
from EWI..Threshold t join
EWI..Period p on t.Period_ID = p.Period_ID where KPI_ID = #kpi_id
) x where (case when [Day] = datename(dw,getdate()) then Period_id
when [Day] = choose(datepart(dw, getdate()), 'WEEKEND','Weekday','Weekday','Weekday','Weekday','Weekday','WEEKEND') then Period_ID
when [Day] = 'All' then Period_ID end) is not null
) y where case when datediff(second,DayStartTime,DayEndTime) > 0 then
case when convert(time(0), #current_timestamp) >= DayStartTime and convert(time(0), #current_timestamp) < DayEndTime then 1 else 0 end
else case when convert(time(0), #current_timestamp) >= DayStartTime or convert(time(0), #current_timestamp) < DayEndTime then 1 else 0 end
end = 1
select 'Run: ' + cast(#kpi_id as varchar(11)) + ' ' + cast(#PeriodID as varchar(11)) + ' ' +
cast(#Threshold_value as varchar(11)) + ' ' + cast(#job_current_time_minute as varchar(11)) + ' ' +
cast(#result as varchar(11)) + ' ' +
cast(ceiling(#result) as varchar(11))+ ' ' +cast(floor(#result) as varchar(11))
end
select #kpi_id = min(kpi_id) from KPI where KPI_Active = 1 and kpi_id > #kpi_id;
end
Take a look at this rextester demo. Do you agree that this model reproduces the problem? It seems that comparing ceiling(#result) to floor(#result) will indeed give everywhere true.
After our discussion it seems to me that the test should be:
if (#result - datepart(minute, Schedule_Start)) % #reoccurrence = 0
or something like that. But this assumes #reoccurence to be an integer.

Grouping within a While Loop, SQL Server

I've been building a while loop to populate a lot of data, and I'm struggling with grouping within the query - I want to add a group on Membership_Level but each time it is returning identical values (the total) for each Level.
Can anyone help me?
Thank you in advance!!!
DECLARE #Counter int
DECLARE #NumPerson int
SET #Counter = 1
WHILE #Counter <= 12
BEGIN
SET #NumPerson = (SELECT
SUM(Amount)
FROM [NewMember]
WHERE LEFT([PERIOD], 4) = 2016
AND GRADE_STATUS = 'N'
AND RIGHT([Period], 2) = #Counter)
SELECT
*
FROM (SELECT
CAST(#NumPerson AS varchar(6)) AS 'Number',
CASE
WHEN LEN(CAST(#Counter AS varchar(2))) = 1 THEN '0' + CAST(#Counter AS varchar(2))
ELSE CAST(#Counter AS varchar(2))
END AS 'Month') s
JOIN (SELECT
MAX('1') AS NGroup,
[PERIOD],
RIGHT([Period], 2) AS 'Month',
MEMBERSHIP_LEVEL
FROM [NewMember]
WHERE LEFT([PERIOD], 4) = 2016
AND GRADE_STATUS = 'N'
GROUP BY [MEMBERSHIP_LEVEL],
[PERIOD],
RIGHT([Period], 2)) t
ON s.[Month] = t.[Month]
SET #Counter = #Counter + 1
END

Subquery is not introduced with exists, stored procedure

I've made a stored procedure and got the error message below, dont know why. I've been looking around for some answers and with some other guys here at the office but they're all unsure of the problem. Hoping someone here has had the same problem and knows the solution to this.
Msg 116, Level 16, State 1, Procedure Name_Stored_Procedure,
Line 113 Only one expression can be specified in the select list
when the subquery is not introduced with EXISTS.
Here is my Code
Set #SQLstring =
'Update #TempTable set Col1' + case when len(Convert(Varchar, (4+#counter)))=1
then '0' else '' end
+ Convert(Varchar,(4+#counter)) + '=''' +
(select #Year, #Month,
Convert(Varchar,count(distinct Table.Column1))
from Databse.Table
where DATEPART(yy,Time) = #Year
and DATEPART(mm,Time) = #Month
and Table.Column2 = #Column2 and Column3 in ('X','Z','Y - A'))
+''' where row = ' + CONVERT(varchar,10+#somevariable * 12)
exec('' + #SQLstring +'')
If you're going to build a string of SQL and execute it with dynamic SQL, then you need to treat it as a string
Set #SQLstring =
'Update #TempTable set Col'
+ case when len(Convert(Varchar, (4+#counter)))=1 then '0' else '' end
...
In your inner select, remove the #year, #month from the results
+ ( select Convert(Varchar,count(distinct Table.Column1)) from databse.Table....
Take the year , month , count in the below part in separate select queries.
(select #Year, #Month,
Convert(Varchar,count(distinct Table.Column1))
from Databse.Table
where DATEPART(yy,Time) = #Year
and DATEPART(mm,Time) = #Month
and Table.Column2 = #Column2 and Column3 in ('X','Z','Y - A'))
select CONCAT(#year, #month, convert....)

The server principal "sa" is not able to access the database under the current security context

I believe there are many StackOverflow posts related to this error, but none seems to have a straightforward solution which I am looking for. I'll be thankful if anyone of you can look into this.
The issue: I am using a dynamic sql stored procedure which uses FundTransfer Database tables in cte expression and then joins with WebbnkDb database.
But, I run into the exception mentioned in the title above. Everything works fine if I remove WITH EXECUTE AS SELF command but unfortunately I can't get rid of it as it is used for some security reasons. Please suggest me solution in easy words.
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
So when you add EXECUTE AS SELF to a procedure, it's the same as saying "Execute this procedure as though the person who created it is running it". So whoever deploys the procedure (under whatever principal account) is the one that will be the basis for what the procedure uses.
I'm presuming that your deployment strategy is to have an administrator run the CREATE/ALTER steps using the sa account. Your DBAs are probably following best practice and not having the sa account own the databases on the server (and possibly not have read access at all), so you get the security error.
Given all that, in your current situation, you're probably not going to use EXECUTE AS SELF, or at least I suspect so. In terms of when you would want to use it in a more general sense, it's hard to give a blanket answer. Short version is if you have a situation where you ("you" being a principal you can log in as) need to run an object at your level of permissions rather than whatever permissions the caller has.