SQL Server : prevent output of tablename with date later then today - sql

I am trying to display data with 11 months from 11 tables. Each table containing a different months data. The table name contains the date of each table. At the moment my code works in a way that a person has to input a date such as 201404 then it will display all months from 201404 right up to 201503. I need to put a check in place so that if the person types in 201507 it only throws out 201507 up to 201510 as the remaining months do not exists as yet.
This is my code:
alter PROCEDURE stp3
#FirstTableMonth int =0,
#EndMonth datetime
AS
DECLARE
#LinkedServerName sysname = 'SERVER1',
#left int = 0,
#right int= 0,
#STRING VARCHAR(6),
#monthex int = 12,
#yearex int,
#yearstring int,
#DynamicSQL nvarchar(max) = '',
#DynamicSQL2 nvarchar(max) = '',
#OpenQuerySql nvarchar(max),
#Table_Name sysname,
#Table_Name2 sysname,
#TableMonth int,
#TableMonth2 int ,
#CurrentMonth int = 0,
#NextYearMonth int = 1,
#part2 nvarchar(max) = '',
#TwelfthMonth int = 0;
SET #FirstTableMonth= CAST(#FirstTableMonth AS VARCHAR(6))
set #left = cast(left(#FirstTableMonth,4) +1 as varchar(max))
set #right = right(#FirstTableMonth,2) - 1
set #monthex = 11
set #yearex = cast(left(#FirstTableMonth,4) as varchar(max))
set #yearstring = case when right(#FirstTableMonth,2) = '01' then left(#FirstTableMonth,4) + RIGHT( #monthex + LTRIM( RTRIM( right(#FirstTableMonth,2) ) ), 6 ) else #left end
SET #STRING =
case when right(#FirstTableMonth,2) = '01' then #yearstring
when #right < 10 then CAST(#left AS VARCHAR(4)) + RIGHT( '0' + LTRIM( RTRIM( #right ) ), 6 )
else CAST(#left AS VARCHAR(4)) + RIGHT( LTRIM( RTRIM( #right ) ), 6 ) end
WHILE #CurrentMonth < 11 AND #EndMonth < getdate()
BEGIN
SELECT #TableMonth = CASE WHEN (#FirstTableMonth + #CurrentMonth) % 100 < 13 THEN
#FirstTableMonth + #CurrentMonth
ELSE
#FirstTableMonth + 100 - (#FirstTableMonth % 100) + #NextYearMonth
END,
#NextYearMonth = CASE WHEN (#FirstTableMonth + #CurrentMonth) % 100 < 13 THEN
#NextYearMonth
ELSE
#NextYearMonth + 1
END,
#Table_Name = 'XX_'+CAST(#TableMonth as varchar)+'_T' ,
#TableMonth2 = #TableMonth,
#Table_Name2 = 'XX_'+CAST(#TableMonth2 as varchar)+'_T' ,
#DynamicSQL = #DynamicSQL +
'SELECT
*
FROM '+ #Table_Name + '
'+ CASE WHEN #CurrentMonth < 10 THEN ' UNION ALL ' ELSE '' END ,
#DynamicSQL2 = #DynamicSQL2 +
'SELECT
*
FROM '+ #Table_Name2 + '
'
SET #CurrentMonth = #CurrentMonth + 1
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL BEGIN DROP TABLE #TEMP END
IF OBJECT_ID('tempdb..#Unioned') IS NOT NULL BEGIN DROP TABLE #Unioned END
--last months snapshot
SELECT
*
INTO #UNIONED
FROM OPENQUERY(SERVER1,' SELECT
*
FROM yy_T
'
)
union all
SELECT
*
FROM OPENQUERY(SERVER1,' SELECT
*
FROM yk
'
)
DECLARE #dateAsNumber VARCHAR(8);
SET #dateAsNumber = CONVERT(CHAR(6),GETDATE(), 112);
DECLARE #DateConvertedFromNumber DATETIME;
SELECT #DateConvertedFromNumber = CONVERT (DATETIME, CONVERT(CHAR(8), #dateAsNumber + '01'))
select
*
LEFT(CONVERT(VARCHAR, DATEADD(MONTH, -1,#DateConvertedFromNumber), 112),6) AS 'Period'
INTO #temp
from #Unioned
drop table OpenQTable
--if equal to month + 99 = previous month then union 11 tables with last months snapshot
--else
--union 11 tables with 12th table
SET #OpenQuerySql = 'IF (' + cast(#FirstTableMonth as varchar) + '+99) = CONVERT(nvarchar(6), dateadd(month,-1,GETDATE()), 112)
BEGIN
SELECT *
FROM OPENQUERY(['+ #LinkedServerName +'], '''+ #DynamicSQL + ''' )
UNION ALL
SELECT *
FROM #temp
END
else
begin
SELECT *
FROM OPENQUERY(['+ #LinkedServerName +'], '''+ #DynamicSQL + ''' )
UNION ALL
SELECT *
FROM OPENQUERY(['+ #LinkedServerName +'], '''+ #DynamicSQL2 + ''' )
end
'
END
insert into OpenQTable
EXECUTE sp_executesql #OpenQuerySql
go
}

Related

How to create a "Catalyst" to view data before x minutes from z timestamp and x minutes after z timestamp for every 'ABC' specific data

" I want a SSRS report that can identify all activations received within the last 5 minutes before the CNT signal was received from a store and signals that were received within 5 minutes after the CNT signal "
Need to know what is the best practice to achieve this goal - what to google to fix my query to make it easier to design in report builder
I have q query below but within SSRS I cant group it or expand it in a way useful for viewing
I have a proof of concept (image) but don't know how to approach the query to get to the result
a bit ambitious for a Jnr report writer!
POC Catalyst Idea <<<<<-
DECLARE #Division varchar(2) = '*',
#SubDivision varchar(4) = '*',
#MainArea varchar(3) = '*',
#SubArea varchar(3) = '*',
#StartD datetime = '2022-03-29',
#StartTime Varchar(10) = '06:00:00',
#EndD datetime = '2022-03-29',
#EndTime Varchar(10) = '18:00:00',
#X int = 5,
#Catylist varchar(3) = 'CNT'
DECLARE #Arc varchar(100),
#Svr varchar(50),
#db varchar(50),
#Str varchar(max) = '',
#Qry varchar(max) = '',
#mon varchar(100) = '',
#StartDate varchar(20),
#EndDate varchar(20)
SET #StartDate = CONVERT(varchar(11),#StartD,106) + ' ' + #StartTime
SET #EndDate = CONVERT(varchar(11),#EndD,106) + ' ' + #EndTime
SELECT #mon = IIF(UPPER(ServerName)=UPPER(##ServerName),DatabaseName,'[' + ServerName + '].' + DatabaseName) + '.dbo.'
FROM maBranchModules WITH (NOLOCK) WHERE Module = 'MONITOR'
CREATE TABLE #FirstBL
(CustId int, Signl varchar(10), StartTime datetime, EndTime datetime,Seq int,Catalyst char(1))
DECLARE Arc_cursor CURSOR FOR
SELECT SQLServer, SQLDatabase FROM RW_ArchiveDTL WITH (NOLOCK)
WHERE StartDTTM >= DATEADD(month,-1,EOMONTH(#StartDate))
AND EndDTTM <= DATEADD(day,1,EOMONTH(#EndDate))
ORDER BY StartDTTM
OPEN Arc_cursor
FETCH NEXT FROM Arc_cursor INTO #Svr, #db
WHILE ##FETCH_STATUS = 0
BEGIN
IF #Svr = ##ServerName
SET #Arc = #db + '.dbo.'
ELSE
SET #Arc = '[' + #Svr + '].' + #db + '.dbo.'
IF #Str = ''
SET #Str = 'INSERT INTO #FirstBL (CustId,Signl,StartTime,Seq)'
ELSE
SET #Str = #Str + char(13) + 'UNION ALL '
/*GET ALL CATYLIST SIGNALS IN DATE RANGE*/
SET #Str = #Str + char(13) + 'SELECT
a.CustId, a.FirstAlarm,a.SignalTime,ROW_NUMBER() OVER (PARTITION BY a.CustId ORDER BY a.SignalTime) AS Seq
FROM ' + #Arc + 'ArchiveHistory AS a WITH (NOLOCK) INNER JOIN
' + #mon + 'Address AS b WITH (NOLOCK) ON a.AddressId = b.AddressId
WHERE a.SignalTime >= ''' + CONVERT(varchar,#StartDate,121) + '''
AND a.SignalTime < ''' + CONVERT(varchar,#EndDate,121) + '''
AND a.FirstAlarm = ''' + #Catylist + '''
AND a.CustId > 0 '
IF #Division <> '*'
SET #Str = #Str + char(13) + 'AND b.Division = ''' + #Division + ''' '
IF #SubDivision <> '*'
SET #Str = #Str + char(13) + 'AND b.SubDivision = ''' + #SubDivision + ''' '
IF #MainArea <> '*'
SET #Str = #Str + char(13) + 'AND a.MainArea = ''' + #MainArea + ''' '
IF #SubArea <> '*'
SET #Str = #Str + char(13) + 'AND a.SubArea = ''' + #SubArea + ''' '
IF #Qry <> ''
SET #Qry = #Qry + char(13) + 'UNION ALL '
/*GET ALL SIGNALS FOR #X MINUTES BEFORE & AFTER CATYLIST SIGNAL RECEIVED*/
SET #Qry = #Qry + char(13) + 'SELECT DISTINCT
--a.CustId, b.StartTime, a.SignalTime, a.FirstAlarm, b.EndTime,
a.CustId, a.SignalTime, a.FirstAlarm, a.OBNumber,
c.CustCode, c.CustDesc, d.Division, d.SubDivision, d.MainArea, d.SubArea, c.SuspendMode
FROM ' + #Arc + 'ArchiveHistory AS a WITH (NOLOCK) INNER JOIN
#FirstBL AS b WITH (NOLOCK) ON a.CustId = b.CustId INNER JOIN
' + #mon + 'Client AS c WITH (NOLOCK) ON a.CustId = c.CustId INNER JOIN
' + #mon + 'Address AS d WITH (NOLOCK) ON c.AddressId = d.AddressId
AND a.SignalTime BETWEEN DATEADD(minute,-' + CONVERT(varchar,#X) + ',b.StartTime) AND b.EndTime '
FETCH NEXT FROM Arc_cursor INTO #Svr, #db
END
CLOSE Arc_cursor;
DEALLOCATE Arc_cursor;
SET #Str = #Str + char(13) + 'ORDER BY CustId, SignalTime'
EXEC(#Str)
/*CLEAN OUT ALL EXTRA CATYLIST SIGNALS THAT FALLS WITHIN #X OF "FIRST"*/
UPDATE #FirstBL SET EndTime = DATEADD(minute,#X,StartTime) WHERE Seq = 1
UPDATE a SET a.Catalyst = IIF(a.StartTime BETWEEN b.StartTime AND b.EndTime,'N','Y')
FROM #FirstBL AS a INNER JOIN
#FirstBL AS b ON a.CustId = b.CustId
WHERE b.Seq = 1
AND a.Seq > 1
DELETE FROM #FirstBL WHERE Catalyst = 'N'
DECLARE #N int
SET #N = 1
WHILE (SELECT COUNT(*) FROM #FirstBL WHERE EndTime IS NULL) > 0
begin
UPDATE #FirstBL SET EndTime = DATEADD(minute,#X,StartTime), Seq = #N + 1
WHERE Seq = (SELECT TOP 1 a.Seq FROM #FirstBL a WHERE #FirstBL.CustId = a.CustId AND Seq > #N ORDER BY a.Seq)
UPDATE a SET a.Catalyst = IIF(a.StartTime BETWEEN b.StartTime AND b.EndTime,'N','Y')
FROM #FirstBL AS a INNER JOIN
#FirstBL AS b ON a.CustId = b.CustId
WHERE b.Seq = #N
AND a.Seq > #N
DELETE FROM #FirstBL WHERE Catalyst = 'N'
Set #N = #N +1
end
/*ALL TOGETHER NOW*/
SET #Qry = #Qry + char(13) + 'ORDER BY CustId, SignalTime'
EXEC(#Qry)
/*GET RID OF THE #*/
DROP TABLE #FirstBL
If you want to look behind and ahead 5 minutes, recommend just using APPLY. For example, here's how to find every match to a "CNT" event within 5 minutes
Using APPLY to Find Events +/- 5 Minutes
DROP TABLE IF EXISTS #Data
CREATE TABLE #Data (
ID INT IDENTITY(1,1) PRIMARY KEY
,SignalDateTime DATETIME2(0)
,FirstAlarm CHAR(3)
)
INSERT INTO #Data VALUES
('2022-03-29 10:06','LRQ')
,('2022-03-29 10:07','CNF')
,('2022-03-29 10:07','CNT')
,('2022-03-29 10:07','DNT')
,('2022-03-29 13:19','LRQ')
,('2022-03-29 13:20','CNF')
,('2022-03-29 13:20','CNT')
,('2022-03-29 13:20','DNT')
,('2022-03-29 13:24','LRQ')
,('2022-03-29 13:24','CNF')
,('2022-03-29 13:24','CNT')
,('2022-03-29 13:24','DNT')
,('2022-03-29 13:25','CNF')
,('2022-03-29 13:25','CNT')
,('2022-03-29 13:25','DNT')
,('2022-03-29 14:31','LRQ')
,('2022-03-29 14:31','CNF')
,('2022-03-29 14:31','CNT')
,('2022-03-29 14:31','DNT')
SELECT CNTGroupID = DENSE_RANK() OVER (ORDER BY A.ID)
,*
FROM #Data AS A
CROSS APPLY (
SELECT *
FROM #Data AS DTA
WHERE DTA.FirstAlarm <> 'CNT'
AND DTA.SignalDateTime BETWEEN DATEADD(mi,-5,A.SignalDateTime) AND DATEADD(mi,5,A.SignalDateTime)
) AS B
WHERE A.FirstAlarm = 'CNT'

Dynamic SQL - parametrized query

I use dynamic sql with parameters and have problem :)
In block of code it works, but when I call procedure I have error that I need to declare scalar variable #name_dummy
So:
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT
o.SCHEMA_N
,o.TABLE_N
,o.Condition
,o.TargetDB
,o.SourceDB
,STUFF((SELECT
', ' + c.name
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH (''))
, 1, 1, '')
FROM Table_A o
ORDER BY 1,
2
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT
SCHEMA_N
,TABLE_N
,CONDITION
,TARGETDB
,SOURCEDB
,COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = ( SELECT CAST(Wartosc AS VARCHAR) FROM Table_B WHERE Id = 3 )
IF #TOP < 40000
SET #TOP = 40000
WHILE ( 1 = 1 )
BEGIN
DECLARE #CHECK BIT = 0
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM '
+ #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
SELECT #sqlCMD , #CHECK
END
END
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
CLOSE KUR;
DEALLOCATE KUR
And when I execute this it's compiling and works ( returns values ) for example sql which I want to execute.
SELECT TOP 1 #check_exists = 1 FROM MSSF15_WarstwaPosrednia.KatalogZdarzen.MSSF_RaportZdarzenPLKB2CS2K WHERE StatusPrzetwarzania = 4 AND DataWpisu < DATEADD(MONTH, -3, #START_TIME)
Parameters work here ( #check_exists which is output and #START_TIME condition param ) , but when I execute this in procedure I'm getting error
Must declare the scalar variable "#START_TIME". 137
SP definition:
USE xxxx
/****** Object: StoredProcedure dbo.dummy Script Date: 06/09/2018 13:40:22 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE dbo.dummy
AS
BEGIN
/*
PRZENIESIENIE DANYCH
*/
DECLARE #START_TIME DATETIME = GETDATE()
DECLARE #TMP_NAMES TABLE (
SCHEMA_N VARCHAR(500),
TABLE_N VARCHAR(500),
CONDITION VARCHAR(MAX),
TARGETDB VARCHAR(500),
SOURCEDB VARCHAR(500),
COLUMN_LIST VARCHAR(MAX)
)
DECLARE #SCHEMA_N VARCHAR(500)
DECLARE #TABLE_N VARCHAR(500)
DECLARE #CONDITION VARCHAR(MAX)
DECLARE #COLUMN_LIST VARCHAR(MAX)
DECLARE #TARGETDB VARCHAR(500)
DECLARE #SOURCEDB VARCHAR(500)
INSERT INTO #TMP_NAMES
SELECT o.SCHEMA_N,
o.TABLE_N,
o.Condition,
o.TargetDB,
o.SourceDB,
STUFF((
SELECT ', ' + c.NAME
FROM sys.columns c
WHERE c.object_id = o.object_id
AND c.system_type_id <> 189 /* Pomijam timestamp*/
ORDER BY c.column_id
FOR XML PATH('')
), 1, 1, '')
FROM dbo.Table_A o
ORDER BY 1,
2
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
DECLARE KUR CURSOR
FOR
SELECT SCHEMA_N,
TABLE_N,
CONDITION,
TARGETDB,
SOURCEDB,
COLUMN_LIST
FROM #TMP_NAMES
OPEN KUR
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
WHILE ##FETCH_STATUS = 0
BEGIN
DECLARE #TOP VARCHAR(100)
SET #TOP = (
SELECT CAST(Wartosc AS VARCHAR)
FROM dbo.Table_B
WHERE Id = 3
)
IF #TOP < 40000
SET #TOP = 40000
WHILE (1 = 1)
BEGIN
BEGIN TRY
BEGIN TRANSACTION T_TEST
DECLARE #CHECK BIT = 0
DECLARE #START_TIME_P DATE = GETDATE()
DECLARE #sqlCMD NVARCHAR(MAX) = 'SELECT TOP 1 #check_exists = 1 FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
SELECT #CHECK,
#START_TIME_P,
#sqlCMD
EXEC sp_executesql #sqlCMD,
N'#check_exists bit OUTPUT, #START_TIME DATE',
#check_exists = #CHECK OUTPUT,
#START_TIME = #START_TIME_P;
IF OBJECT_ID('tempdb..#TMP_ID') IS NOT NULL
DROP TABLE #TMP_ID
CREATE TABLE #TMP_ID (Id INT)
EXEC (
'INSERT INTO #TMP_ID
SELECT TOP ' + #TOP + ' Id
FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE ' + #CONDITION
)
DECLARE #sqlCMD_Ins NVARCHAR(MAX)
SET #sqlCMD_Ins = 'INSERT INTO ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' '
SET #sqlCMD_Ins = #sqlCMD_Ins + 'SELECT ' + #COLUMN_LIST + ' FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Ins IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Ins)
DECLARE #sqlCMD_Del NVARCHAR(MAX)
SET #sqlCMD_Del = 'DELETE FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' WHERE Id IN ( SELECT Id FROM #TMP_ID )'
IF #sqlCMD_Del IS NULL
RAISERROR (
'Brak polecenia insert #sqlCMD_Ins',
16,
1
)
EXEC (#sqlCMD_Del)
DROP TABLE #TMP_ID
COMMIT TRANSACTION T_TEST
END TRY
BEGIN CATCH
IF (##TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION T_TEST
PRINT 'Wycofanie zmian'
PRINT ERROR_MESSAGE() + ' ' + CAST(ERROR_NUMBER() AS VARCHAR(256))
END
END CATCH
IF #CHECK = 0
BREAK
END
EXEC ('SELECT ''' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #SOURCEDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ' UNION ALL ' + 'SELECT ''' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N + ''' AS DB ,COUNT(1) AS ILOSC FROM ' + #TARGETDB + '.' + #SCHEMA_N + '.' + #TABLE_N)
FETCH NEXT
FROM KUR
INTO #SCHEMA_N,
#TABLE_N,
#CONDITION,
#TARGETDB,
#SOURCEDB,
#COLUMN_LIST
END
CLOSE KUR;
DEALLOCATE KUR;
DECLARE #END_TIME DATETIME = GETDATE()
SELECT 'Daty przetworzenia',
#START_TIME_P AS 'START',
#END_TIME AS 'END'
SELECT 'Czas (min)',
DATEDIFF(MINUTE, #START_TIME_P, #END_TIME)
END
Guys, maybe u have similar situation and can help.
Error msg
Wycofanie zmian
Must declare the scalar variable "#START_TIME". 137
Thanks
Instead of
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #START_TIME;
try
declare #date_in DATE = GETDATE()
exec sp_executesql #sqlCMD, N'#check_exists bit OUTPUT, #START_TIME DATE', #check_exists = #CHECK OUTPUT, #START_TIME = #date_in;

Get value from table while executing SP

I have several stored procedures that run daily/weekly/monthly that email resultset in HTML format. I declare a value on each of them as a "Goal" to divide by. This works great but it is very time consuming when we need to change the value of each "Goal". I want to store all the values in a table and have the SP call on that table to get value of "Goal". I am showing one of the SPs for an example and will also show the table i have created as GoalSetUp
DECLARE
#Offset INT ,
#Start DATETIME ,
#End DATETIME ,
#VC CHAR(2) ,
#ap CHAR(2) ,#Goal VARCHAR(10)
---------------------------------------------------
SET #VC = 'VC'
SET #ap = 'ap'SET #Goal= '15'
SET #Offset = 1
SET #Start = dateadd(day, datediff(day, 0, getdate()), -#Offset)
SET #End = dateadd(day, datediff(day, 0, getdate()), -#Offset)
--VC AP--
DECLARE #23 varchar(max) DECLARE #Head23 varchar(max) DECLARE #Tail23 varchar(max)
DECLARE #mailitem_id23 as int DECLARE #statusMsg23 as varchar(max)DECLARE #Error23 as varchar(max) DECLARE #Note23 as varchar(max)
SET NoCount On;
SET #mailitem_id23 = null SET #statusMsg23 = null SET #Error23 = null SET #Note23 = null SET #Tail23 = '</table></body></html>'; SET #Head23 =
'<html><head>' + '<style>' +
'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:9pt;color:Black;} ' +
'</style>' + '</head>' + '<body><table cellpadding=0 cellspacing=0 border=0 width=100%>' + '<tr bgcolor=#808080>'+
'<td width=5%><b>Codes</b></td>'+'<td width=5%><b>TimeSUM</b></td>'+'<td width=5%><b>Units</b></td>'+'<td width=5%><b>UPH</b></td>'+'<td width=5%><b>Goal%</b></td>'+'<td width=5%><b>ID</b></td>'+'<td width=10%><b>Associate Name</b></td></tr>';
SELECT #23= (SELECT
[TD] = (t.DeptCode + '-' + t.OpCode)
,[TD] = right(convert(varchar(9),(sum(datediff(second,StartTime,FinishTime)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) / 60) % 60 ),2)
,[TD] = PARSENAME(convert(varchar,cast(sum(units) as money),1),2)
,[TD] = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60 as decimal(10,0))
,[TD] = isnull((convert(varchar(30),cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/nullif(#Goal,0)*100 as decimal(10,0))) + '%'), ' ')
,[TD] = t.ID
,[TD] = UPPER(isnull(ai.FirstName + ' ','**********fix me') + isnull(ai.LastName,''))
FROM TimeLog t left join AssociateInfo ai on t.Id = ai.Id where t.EventDate >= #Start and t.EventDate <= #End and t.DeptCode = #VC and t.OpCode = #ap group by t.EventDate, t.id, t.DeptCode, t.OpCode, ai.FirstName, ai.LastName
ORDER BY cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60 as decimal(10,0)) desc
FOR XML RAW('tr'), ELEMENTS)
SET #23 = REPLACE(#23, '_x0020_', SPACE(1))SET #23 = REPLACE(#23, '_x003D_', '=')SET #23 = REPLACE(#23, '<tr><TRRow>1</TRRow>', '<tr bgcolor=#C6CFFF>')SET #23 = REPLACE(#23, '<TRRow>0</TRRow>', '')SET #23 = #Head23 + #23 + #Tail23
Select #23
-----------------------------------------------------------------
-----------------------------------------------------------------
--Email
DECLARE #Body VARCHAR(MAX)
SET #Body = ISNULL(#23, ' ')
EXEC msdb.dbo.sp_send_dbmail
#profile_name ='myprofile',
#recipients = 'myemail#myemail.com',
#subject = 'Email',
#body = #Body,
#body_format = 'HTML'
GoalSetUp table
DeptCode OpCode Goal Location
VC ap 15 10
Is there a way i can call on GoalSetUp table to retreive the value of Goal For #Goal value used in my SP?
SET #Goal= (select Goal from GoalSetUp where /*conditions returning one row here*/)
You must edit your stored procedures in order to take a dynamic value for #Goal.
Something like this
DECLARE
#Offset INT ,
#Start DATETIME ,
#End DATETIME ,
#VC CHAR(2) ,
#ap CHAR(2) ,
#Goal VARCHAR(10)
---------------------------------------------------
SET #VC = 'VC'
SET #ap = 'ap'
SELECT #Goal= GOAL FROM GOALTable --change this row
SET #Offset = 1
SET #Start = dateadd(day, datediff(day, 0, getdate()), -#Offset)
SET #End = dateadd(day, datediff(day, 0, getdate()), -#Offset)

Passing parametrs to dynamic query

I have a stored procedure as following, I need to pass paramters to the dynamic pivot. My query runs, I just need to do some filtering based on the passed parameters
-- AND (#SelectedSystemIDs IS NULL OR System.ID IN(select * from dbo.SplitInts_RBAR_1(#SelectedSystemIDs, ',')))
--AND ((#PlatformID IS NULL) OR (System.PlatformID = #PlatformID) OR (#PlatformID = 12 AND System.PlatformID <= 2))
-- AND (ServiceEntry.ServiceDateTime between #StartDate and #EndDate)
so I want to add the above criteria, how could achieve that?
ALTER PROCEDURE [dbo].[spExportStuff]
(#StartDate datetime,
#EndDate datetime,
#SelectedSystemIDs nvarchar (2000) = NULL,
#SelectedTsbIDs nvarchar (2000) = NULL,
#UserRoleID int
)
AS
DECLARE #InstrumentType int = NULL
DECLARE #PlatformID int = null
IF (#SelectedSystemIDs = '')
begin
SET #SelectedSystemIDs = NULL
END
IF (#SelectedTsbIDs = '')
begin
SET #SelectedTsbIDs = NULL
END
IF(#UserRoleID = 1)
BEGIN
SET #PlatformID = 1
END
IF(#UserRoleID = 2)
BEGIN
SET #PlatformID = 2
END
IF (#UserRoleID = 3)
BEGIN
SET #PlatformID = 12
END
IF(#UserRoleID = 4)
BEGIN
SET #PlatformID = 3
END
IF(#UserRoleID = 5)
BEGIN
SET #PlatformID = 4
END
IF(#UserRoleID = 6)
BEGIN
SET #PlatformID = NULL
END
DECLARE #PivotColumnHeaders NVARCHAR(MAX)
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',[' + cast(SystemFullName as Nvarchar) + ']',
'[' + cast(SystemFullName as varchar)+ ']'
)
FROM System
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
Group By TSBNumber, SystemFullName, ClosedDate
) AS PivotData
PIVOT (
max(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE(#PivotTableSQL)
you can construct the required criteria as another input to the stored procedure and append it to the dynamic query
ALTER PROCEDURE [dbo].[spExportStuff]
(#StartDate datetime,
#EndDate datetime,
#SelectedSystemIDs nvarchar (2000) = NULL,
#SelectedTsbIDs nvarchar (2000) = NULL,
#UserRoleID int,
#WhereClause varchar(max) -> this is the new parameter.
)
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
Group By TSBNumber, SystemFullName, ClosedDate
) AS PivotData
PIVOT (
max(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
' + #WhereClause -> you can append the where clause here.
EXECUTE(#PivotTableSQL)

Looping in a dynamic sql query

I've nearly got this dynamic query working:
DECLARE
#ord int = 1,
#wght int = 0,
#bit int,
#colname varchar(max),
#col2 varchar(max),
#sstr varchar(max),
#fstr varchar(max),
#wstr varchar(max),
#sum varchar(max) = ' 0',
#colist varchar(max) = '',
#frlist varchar(max) = '',
#whlist varchar(max) = '',
#sql varchar(max)
WHILE #wght < 2
BEGIN
SET #wght = #wght + 1
WHILE #ord < 3
BEGIN
SET #ord = #ord + 1
SELECT #colname = BR FROM dbo.[Y2 Ordinal] WHERE ORDINAL_POSITION= #ord
SET #sstr = '(A.' + #colname + '*B' + CAST(#wght AS varchar(max))+'.' + #colname +')'
SET #sum = #sum + '+' + #sstr
END
SELECT #w = [ID NO] FROM dbo.[Weightings] WHERE [ID NO]= #wght
SET #fstr = ' dbo.[Weightings] AS B' + CAST(#wght AS varchar(max))
SELECT #col2 = [Batch ID] FROM dbo.[Weightings] WHERE [ID NO]= #wght
SET #wstr = 'B' + CAST(#wght AS varchar(max)) + '.[Portfolio ID] = ' + '''' + #col2 + ''''
SET #colist = #colist + ',' +(#sum)+' AS ' +''''+(#col2)+''''
SET #frlist = #frlist + ',' +(#fstr)
SET #whlist = #whlist + ' AND ' +(#wstr)
END
SET #sql = '(SELECT A.Sim' + #colist+ ' FROM dbo.[Y2 Net of Fees] As A' + #frlist +' WHERE A.[Simulation] IS NOT NULL ' + #whlist + ')ORDER BY Simulation'
PRINT(#sql);
The output sql statement (reformatted here) is:
(SELECT A.Sim,
0+(A.[Apples]*B1.[Apples])+(A.[Oranges]*B1.[Oranges]) AS 'Batch A',
0+(A.[Apples]*B1.[Apples])+(A.[Oranges]*B1.[Oranges]) AS 'Batch B'
FROM dbo.[Fruit] As A,
dbo.[Weightings] AS B1,
dbo.[Weightings] AS B2
WHERE A.[Simulation] IS NOT NULL
AND B1.[Batch ID] = 'Batch A'
AND B2.[Batch ID] = 'Batch B')
ORDER BY Simulation
My desired output is:
SELECT A.Sim,
0+(A.[Apples]*B1.[Apples])+(A.[Oranges]*B1.[Oranges]) AS 'Batch A',
0+(A.[Apples]*B2.[Apples])+(A.[Oranges]*B2.[Oranges]) AS 'Batch B'
So my problem is the #wght remaining static in the second while loop, I was thinking the when it increased in the first loop it would feed into the second. Any suggestions?
USE APPLICATION
GO
SET NOCOUNT ON
IF OBJECT_ID('tempdb.dbo.#Y2_Ordinal') IS NOT NULL
BEGIN
DROP TABLE #Y2_Ordinal
END
IF OBJECT_ID('tempdb.dbo.#Weightings') IS NOT NULL
BEGIN
DROP TABLE #Weightings
END
GO
CREATE TABLE #Y2_Ordinal(
COLUMN_NAME VARCHAR(100)
,ORDINAL_POSITION INT
);
CREATE TABLE #Weightings(
[Batch ID] INT
,[ID NO] INT
);
GO
INSERT INTO #Y2_Ordinal
(COLUMN_NAME
,ORDINAL_POSITION)
VALUES('Apples'
,'1')
INSERT INTO #Y2_Ordinal
(COLUMN_NAME
,ORDINAL_POSITION)
VALUES('Oranges'
,'2')
--SELECT * FROM #Y2_Ordinal
--INSERT INTO #Y2_Ordinal
-- (COLUMN_NAME
-- ,ORDINAL_POSITION)
-- VALUES('Grapes'
-- ,'3')
INSERT INTO #Weightings VALUES('1','1')
INSERT INTO #Weightings VALUES('2','2')
INSERT INTO #Weightings VALUES('3','3')
DECLARE
#ord int = 1,
#wght int = 0,
#bit int,
#colname varchar(max),
#col2 varchar(max),
#sstr varchar(max),
#fstr varchar(max),
#wstr varchar(max),
#sum varchar(max) = '',
#colist varchar(max) = '',
#frlist varchar(max) = '',
#whlist varchar(max) = '',
#sql varchar(1000),
#w VARCHAR(max)
WHILE #wght < 2
BEGIN
SET #wght = #wght + 1
--PRINT(#wght)
SET #ord = 1
Set #sum = ''
WHILE #ord < 3
BEGIN
--PRINT('ord' + CAST(#ord AS VARCHAR(100)))
SELECT #colname = COLUMN_NAME FROM #Y2_Ordinal WHERE ORDINAL_POSITION= #ord
--PRINT(#colname)
SET #sstr = '(A.' + #colname + '*B' + CAST(#wght AS varchar(max))+'.' + #colname +')'
--PRINT(#sstr)
SET #sum = #sum + '+' + #sstr
--PRINT(#sum)
SET #ord = #ord + 1
END
SELECT #w = [ID NO] FROM #Weightings WHERE [ID NO]= #wght
SET #fstr = ' dbo.[Weightings] AS B' + CAST(#wght AS varchar(max))
SELECT #col2 = [Batch ID] FROM #Weightings WHERE [ID NO]= #wght
--PRINT ('col2' + #col2)
SET #wstr = 'B' + CAST(#wght AS varchar(max)) + '.[Portfolio ID] = ' + '''' + #col2 + ''''
SET #colist = #colist + ', 0' +(#sum)+' AS ' +''''+(#col2)+''''
--PRINT ('col_list' + #colist)
SET #frlist = #frlist + ',' +(#fstr)
SET #whlist = #whlist + ' AND ' +(#wstr)
END
--PRINT(#colist)
--PRINT(#frlist)
--PRINT(#whlist)
SET #sql = '(SELECT A.Sim' + #colist+ ' FROM dbo.[Y2 Net of Fees] As A'
+ #frlist +' WHERE A.[Simulation] IS NOT NULL '
+ #whlist + ')ORDER BY Simulation'
PRINT #SQL