Is there any way I can add a column to a table but I want the heading to be a date, and every new column added will have a column heading for the next day hence the
SET #date1 = #date1 + 1
What I want the table to look like is, where the date on top is a new column for each day the script loops:
StoreID StoreName 02/01/12 03/01/12 04/01/12
1234 Coles1 7512 8574
1235 Coles2 7210 8441
1236 Coles3 4845 5448
When I run the script I get the following error messages:
Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near '#Column'.
Msg 170, Level 15, State 1, Line 1
Line 1: Incorrect syntax near '#Column'.
Here is my script:
DECLARE #date datetime
DECLARE #date1 datetime
DECLARE #date2 datetime
DECLARE #Column varchar(8)
SET #date = '02 Jan 2012'
SET #date1 = '02 Jan 2012'
SET #date2 = '08 Jan 2012'
SET #Column = CONVERT(VARCHAR(8), #date1, 3)
IF NOT EXISTS (SELECT * FROM sysobjects WHERE xtype = 'U' AND name = '#vl_temp_trans')
BEGIN
CREATE TABLE #vl_temp_trans
(StoreID INT,
StoreName VARCHAR(100),
#Column MONEY) ----> column name to be date "#Column)
END
WHILE (#date1 <= #date2)
BEGIN
SET #Column = CONVERT(VARCHAR(8), #date1, 3)
ALTER table #vl_temp_trans
ADD #Column MONEY ----> column name to be date "#Column"
Insert into #vl_temp_trans (storeID, storeName, #Column)
select storeId, storeName, TotalDailyTransactions
from daily_trans t1 (nolock)
full outer join outlets t2 (nolock) on t1.StoreID = t2.StoreID
where DailyEnd = #date1 + 1
SET #date1 = #date1 + 1
END
You can't do this without dynamic SQL. Here is a query that will get you the result you want. You are more than welcome to uncomment the --INTO #t bit, however it is unclear what you want to do with the #temporary table beyond that (if you tell us the end result, instead of "I want to add a column name as #column, maybe we can help with that too). In order to continue referencing that #t table, you'll need to continue using code within the same scope - meaning more dynamic SQL that is executed within the same sp_executesql call.
DECLARE
#start DATE = '2012-01-02',
#end DATE = '2012-01-08';
DECLARE
#sql NVARCHAR(MAX) = N'',
#colMax NVARCHAR(MAX) = N'',
#colNames NVARCHAR(MAX) = N'';
;WITH x(rn) AS ( SELECT TOP (DATEDIFF(DAY, #start, #end) + 1) ROW_NUMBER()
OVER (ORDER BY [object_id]) - 1 FROM sys.all_columns ),
y(d) AS ( SELECT CONVERT(CHAR(10), DATEADD(DAY, rn, #start)) FROM x
)
SELECT #colMax += N',' + CHAR(13) + CHAR(10)
+ QUOTENAME(d) + ' = SUM(CASE WHEN DailyEnd = '''
+ d + ''' THEN TotalDailyTransactions ELSE 0 END)',
#colNames += N',' + QUOTENAME(d) FROM y;
SET #sql = 'SELECT StoreID, StoreName, ' + STUFF(#colNames, 1, 1, '')
+ ' --INTO #t
FROM ( SELECT StoreID, StoreName, ' + STUFF(#colMax, 1, 1, '')
+ ' FROM dbo.daily_trans
WHERE DailyEnd >= ''' + CONVERT(CHAR(10), #start) + ''''
+ ' AND DailyEnd < ''' + CONVERT(CHAR(10), DATEADD(DAY, 1, #end)) + '''
GROUP BY StoreID, StoreName
UNION ALL SELECT StoreID, StoreName, ' + STUFF(#colMax, 1, 1, '')
+ ' FROM dbo.outlets
WHERE DailyEnd >= ''' + CONVERT(CHAR(10), #start) + ''''
+ ' AND DailyEnd < ''' + CONVERT(CHAR(10), DATEADD(DAY, 1, #end)) + '''
GROUP BY StoreID, StoreName) AS x';
PRINT #sql;
-- EXEC sp_executesql #sql;
I think the problem is that you can't use a variable to define a column name.
I used some of your code to test with. This first part executed fine.
DECLARE #date1 datetime
DECLARE #Column varchar(8)
SET #date1 = '02 Jan 2012'
SET #Column = CONVERT(VARCHAR(8), #date1, 3)
select #Column
But when I added the CREATE TABLE statement and executed all of it at once, then I got the same error you did.
CREATE TABLE #vl_temp_trans
(StoreID INT,
StoreName VARCHAR(100),
#Column MONEY) ----> column name to be date "#Column)
To do this you will need to build up the CREATE TABLE and ALTER TABLE statements as a string and then execute those using EXECUTE or sp_executesql. A search for "dynamic sql" will also give you some article that describe this too.
There is two things you need to do to execute this code...
Create dynamic sql make use of SP_ExecuteSQl
you need to make your temp table Gobal because when you create private temp table it remain in scope of dyanic sql sp only
have look to below code which is updated by me sure reslove your issue
DECLARE #date datetime
DECLARE #date1 datetime
DECLARE #date2 datetime
DECLARE #ColumnNAAME varchar(8)
Declare #Query NVARCHAR(1000)
DECLARE #ParmDefinition NVARCHAR(500);
SET #date = getdate()
SET #date1 = getdate()
SET #date2 = getdate()
SET #ColumnNAAME = CONVERT(VARCHAR(8), #date1, 3)
IF NOT EXISTS (SELECT * FROM sysobjects WHERE xtype = 'U' AND name = '#vl_temp_trans')
BEGIN
SET #ParmDefinition = N'#Column varchar(8)';
Set #Query = 'CREATE TABLE ##vl_temp_trans (StoreID INT, StoreName VARCHAR(100), ['+#ColumnNAAME+'] MONEY)'
EXECUTE sp_executesql #Query,#ParmDefinition,
#Column = #ColumnNAAME;
----> column name to be date "#Column)
SELECT * from ##vl_temp_trans
END
ELSE
BEGIN
SELECT * from ##vl_temp_trans
END
Related
I have a table which can output any number of different columns (from 'Level1' to 'Level'N).
I need to perform a left join on each of these dynamic columns against a CTE
I have written the following script but keep getting this error:
Msg 102, Level 15, State 1, Line 15 Incorrect syntax near '10'.
To troubleshoot, I have tried removing the each of the variables in the CTE with no luck.
Any help would be much appreciated!
DECLARE #rel varchar(4) = CAST('X112' AS varchar(4))
DECLARE #todaysdate date = CONVERT(date,GETDATE())
--create cte
DECLARE #sqltext varchar(MAX) =
' WITH CTE AS
(
SELECT
ID
,STARTDATE
,ENDDATE
,NEWID
FROM Tbl
WHERE TYPE = ''' + #rel + '''
AND ENDDATE >= ' + CAST(#todaysdate AS varchar(30)) +' AND STARTDATE <= ' + CAST(#todaysdate AS varchar(30)) +'
)
SELECT ID, NEWID, Level';
--find max lvl, convert to str
DECLARE #counter int = (SELECT MAX(lvl) FROM tbl2)
DECLARE #counterstring varchar(3)
SET #counterstring = CAST(#counter AS varchar(3))
WHILE #counter != 0
BEGIN
SET #sqltext = #sqltext + #counterstring + ' INTO tbl3 '
+ ' FROM tbl2 a '
+ ' LEFT JOIN CTE c ON a.Level' + #counterstring + ' = c.NEWID'
SET #counter = #counter - 1
END
EXEC(#sqltext)
--edited version
DECLARE #rel varchar(4) = CAST('X112' AS varchar(4))
DECLARE #todaysdate date = CONVERT(date,GETDATE())
DECLARE #sqltext varchar(MAX) =
' WITH CTE AS
(
SELECT
ID
,STARTDATE
,ENDDATE AS mgmt_ENDDA
,NEWID
FROM tbl
WHERE SUBTY = ''' + #rel + '''
AND ENDDATE >= ' + CAST(#todaysdate AS varchar(30)) +' AND STARTDATE <= ' + CAST(#todaysdate AS varchar(30)) +'
)
INSERT INTO tbl3
SELECT ID, NEWID, Level';
DECLARE #counter int = (SELECT MAX(lvl) FROM tbl2)
DECLARE #counterstring varchar(3)
WHILE #counter != 0
BEGIN
SET #counterstring = CAST(#counter AS varchar(3))
SET #sqltext = #sqltext + #counterstring
+ ' FROM tbl2 a '
+ ' LEFT JOIN CTE c ON a.Level' + #counterstring + ' = c.NEWID'
SET #counter = #counter - 1
END
EXEC(#sqltext)
Since select * into query creates a new table each time, I am assuming that you are trying to create 'n' number of tables for 'n' number of levels, with the result obtained by joining with nth column. I have 2 suggestions for you
Bring the select query within the while loop and append ';' at the end of the loop to split select queries.
instead of INTO tbl3 use INTO tbl + #counterstring as select * into will create new table
Hope this helps you
Can you change it like this and try again?
--edited version
DECLARE #rel varchar(4) = CAST('A012' AS varchar(4))
DECLARE #todaysdate date = CONVERT(date,GETDATE())
DECLARE #sqltext varchar(MAX) =
' WITH CTE AS
(
SELECT
ID
,STARTDATE
,ENDDATE AS mgmt_ENDDA
,NEWID
FROM tbl
WHERE SUBTY = ''' + #rel + '''
AND ENDDATE >= ' + CAST(#todaysdate AS varchar(30)) +' AND STARTDATE <= ' + CAST(#todaysdate AS varchar(30)) +'
)
INSERT INTO tbl3';
DECLARE #counter int = (SELECT MAX(lvl) FROM tbl2)
DECLARE #counterstring varchar(3)
WHILE #counter != 0
BEGIN
SET #counterstring = CAST(#counter AS varchar(3))
SET #sqltext = #sqltext + CHAR(10) +'SELECT ID, NEWID, Level'+#counterstring
SET #sqltext = #sqltext + ' FROM tbl2 a '
+ ' LEFT JOIN CTE c ON a.Level' + #counterstring + ' = c.NEWID'
SET #counter = #counter - 1
IF #counter <> 0
SET #sqltext = #sqltext + CHAR(10) + ' UNION '
END
EXEC(#sqltext)
You can try 'UNION ALL' instead of 'UNION' if you dont want to get rid of duplicate data. Hope this helps
I have a SQL Server database with date representation name like below & each database contains table A (table A having column like id, datetime, value, value1 etc).
Jan2018
Feb2018
Mar2018 and so on..
My search condition is user selected date (eg. from 01-Jan-2018 to 01-Jun-2018) which I am passing to a stored procedure (max range 6 month). I want to generate dynamic query to get data from these database based on datetime passed.
How to achieve this functionality as I found difficult to implement.
Can you try this query
CREATE PROCEDURE Myproc #FromDate DATE,
#ToDate DATE
AS
BEGIN
DECLARE #SQL NVARCHAR(max)='',
#unionall VARCHAR(10)=''
WITH cte
AS (SELECT #FromDate dt,
1 mont
UNION ALL
SELECT Dateadd(month, 1, dt) dt,
mont + 1 mont
FROM cte
WHERE mont < Datediff(month, #FromDate, #ToDate)
)
SELECT #SQL += #unionall + '
select * from ['
+ LEFT (CONVERT(VARCHAR, Datename (month, dt )), 3)
+ CONVERT (VARCHAR, Year (dt))
+ '].[dbo].[tablename]',
#unionall = ' union all '
FROM cte
PRINT #SQL
EXECUTE( #SQL)
END
You should query sys.databases to find a database you need.
Then, as you can only use static declarations of databases, you should create a textual select statement and execute it.
I tried it on my dbs and it worked.
This is my code:
declare #date varchar(20) = '2018'
declare #dbName varchar(20)
declare #sSql varchar(200)
declare #sConditions varchar(20) = ''
Set #dbName = (SELECT name FROM master.sys.databases
where name like '%' + #date + '%')
print #dbName
Select #sSql = 'Select * From ' + #dbName + '.dbo.MyDB '
--+ ' Where ' + #sConditions
Execute (#sSql)
if you need to query all that fit year. do like this:
declare #date varchar(20) = 'a'
SELECT name Into #dbnames
FROM master.sys.databases
where name like '%' + #date + '%'
this brings a table of all sutable dbs. then query each one of them using loop. like cursor
Are you looking for
CREATE PROCEDURE MyProc
#FromDate DATE,
#ToDate DATE,
#Target SysName
AS
BEGIN
DECLARE #SQL NVARCHAR(MAX)= N'SELECT * FROM [' +
#Target +
'] WHERE [Dates] >= #FromDate AND [Dates] <= #ToDate';
EXECUTE sp_executesql #SQL,
N'#FromDate DATE, #ToDate DATE',
#FromDate,
#ToDate;
END
Demo
As I now understand what you are trying to do, you can
CREATE PROCEDURE ProcName
#FromDate DATE,
#ToDate DATE
AS
BEGIN
--Declare a variable to hold the Dynamic SQL
DECLARE #SQL NVARCHAR(MAX) = N'';
--Generate the databases names
WITH CTE AS
(
SELECT #FromDate D,
1 N
UNION ALL
SELECT DATEADD(Month, N, #FromDate),
N + 1
FROM CTE
WHERE N <= DATEDIFF(Month, #FromDate, #ToDate)
)
--Build the SELECT statement
SELECT #SQL = #SQL+
N'SELECT * FROM ['+
CONVERT(VARCHAR(3), D, 100)+
CAST(YEAR(D) AS VARCHAR(4))+
'].dbo.TableName UNION ALL ' --Or UNION as you want
FROM CTE;
--Remove the last UNION ALL
SET #SQL = LEFT(#SQL, LEN(#SQL) - 10); --If UNION then just -6
--Execute the statement
EXECUTE sp_executesql #SQL;
END
Guru's please help me with this.
I have a master table called ABC, each month we create new table and suffix with month and year ABC_012010, ABC_022010.
I have to keep these tables for 7 years, and delete any table which are more than 7 years.
So the job would delete ABC_012010 in Feb 2017, ABC_022010 would be deleted in March 2017 and so on
The job runs every month to check and delete any table, which fits the criteria.
TRY THIS: You need dynamic query, loop and temporary tables to perform this operation and your table format must be in the same format as you have mentioned in your example. You can perform INSERT, UPDATE, DELETE, DROP, TRUNCATE in this way in multiple tables:
--Selecting table name in date format with `LEFT` `RIGHT` function
SELECT name,
CAST(CONCAT(LEFT(RIGHT(name, 6), 2), '-01-', RIGHT(RIGHT(name, 6), 4)) AS DATE) AS tableDate,
CAST(GETDATE() AS DATE) AS currentDate
INTO #tmp_date
FROM sys.objects
WHERE TYPE = 'u' AND NAME LIKE 'ABC[_]%'
--Storing table names that are older than 7 years from current date
SELECT id = IDENTITY(INT, 1, 1),
NAME
INTO #object_name FROM #tmp_date
WHERE (DATEDIFF(MM,tableDate, currentDate)-1) > = 84
DECLARE #i INT = 1, #j INT, #sql VARCHAR(500), #object_name VARCHAR(100)
SELECT #j = MAX(id) FROM #object_name
WHILE #i < = #j
BEGIN
SELECT #object_name = NAME FROM #object_name WHERE id = #i
SET #sql = 'DELETE FROM ' + #object_name --can use `DROP` to drop the table
EXEC (#sql)
SET #i = #i+1
END
try the following:
IF OBJECT_ID('TEMPDB.DBO.#TEMP_DEL', 'U') IS NOT NULL
DROP TABLE #TEMP_DEL
DECLARE #CYMO VARCHAR(8) = (SELECT '01' + RIGHT(REPLACE(CONVERT(CHAR(10), DATEADD(YY, -7, GETDATE()), 103), '/', ''), 6))
SELECT [NAME] TABLE_NAME INTO #TEMP_DEL FROM DBNAME.SYS.TABLES
WHERE [NAME] LIKE 'ABC%' AND '01'+RIGHT(NAME,6) < #CYMO
WHILE ((SELECT COUNT(1) FROM #TEMP_DEL) > 0)
BEGIN
DECLARE #TAB VARCHAR(100) = (SELECT TOP 1 TABLE_NAME FROM #TEMP_DEL)
DECLARE #CMD NVARCHAR(200) = 'DROP TABLE '+#TAB
EXEC SP_EXECUTESQL #CMD
DELETE #TEMP_DEL WHERE TABLE_NAME = #TAB
END
Replace DBNAME with your database name.
HTH!
Thanks.
You could use dynamic query, while and if conditionals to construct a stored procedure or scheduled job (as you like) to solve this issue. Try this.
CREATE PROCEDURE dbo.delete_abc #Date date, #years_diff int
AS
--- Declare variables to use
DECLARE #sqlCommand varchar(30)
DECLARE #table varchar(20)
DECLARE #month int
DECLARE #year int
--- Temporary table with 'ABC_'s table names
SELECT TABLE_NAME
INTO #Temp
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'ABC_%'
AND TABLE_TYPE='BASE TABLE' -- If you want only tables
---- While there are tables to compare
WHILE EXISTS(SELECT * FROM #Temp)
BEGIN
--- Extract Month and Year of the first row in 'ABC_'s table
SET #month = (SELECT TOP 1 SUBSTRING(TABLE_NAME,5,2) FROM #Temp)
SET #year = (SELECT TOP 1 SUBSTRING(TABLE_NAME,7,4) FROM #Temp)
--- Compare if date difference of the table is more than #years_diff years from #Date
IF DATEDIFF(YEAR, CAST(CAST(#year AS VARCHAR) + '-' + CAST(#month AS VARCHAR) + '-01' AS DATE), DATEADD(MONTH, DATEDIFF(MONTH, 0, #Date), 0)) > #years_diff
BEGIN
--- Construct and execute delete query
SET #table = (SELECT TOP 1 TABLE_NAME FROM #Temp)
SET #sqlCommand = 'DROP TABLE ' + #table --- or 'DELETE FROM ' if you only want to delete all rows from table
EXEC(#sqlCommand)
END
--- Delete first row of 'ABC_'s tables in temporary
DELETE TOP (1) FROM #Temp;
END
--- Drop temporary table
DROP TABLE #Temp
GO;
Once it's created, you can use this stored procedure like this or with the parameters you like:
DECLARE #Now date
SET #Now = GETDATE()
EXEC dbo.delete_abc #years_diff = 7, #Date = #Now
Wouldn't it be easy enough to make a delete query?
Delete From [Your_Table] Where [Date_Column] = 'ABC_012010'
This question already has answers here:
Rows to Columns in SQL Server 2000
(2 answers)
Closed 8 years ago.
I have a script gaind from a website that creates a table of data i then export to excel. This works great in SQL 2005+ but unfortunately i have 2 legacy servers that i would also like to run this on.
I have tried and tried to get this to work but can not get the data to display in the same way.
SCRIPT:
--
****************************************************************************************
-- This script returns a (graphical) timeline for all SQL jobs
--****************************************************************************************
-- Version: 1.0
-- Author: Theo Ekelmans
-- Email: theo#ekelmans.com
-- Date: 2013-01-11
--****************************************************************************************
set nocount on
declare #Minutes table (DT datetime)
declare #JobNames table (JobName varchar(255))
declare #DT datetime
declare #StartDT datetime
declare #EndDT datetime
declare #Resolution int
declare #RemoveNonactiveJobs int
declare #IgnoreDisabledJobs int
--***************************************************************************************
-- Set variables
--***************************************************************************************
set #StartDT = getdate() - 1
set #EndDT = getdate()
set #Resolution = 1 -- Enter the Resolution in minutes
set #RemoveNonactiveJobs = 1
set #IgnoreDisabledJobs = 1
--***************************************************************************************
-- Pre-run cleanup (just in case)
--***************************************************************************************
IF OBJECT_ID('tempdb..#Timeline') IS NOT NULL DROP TABLE #Timeline;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
IF OBJECT_ID('tempdb..#Pivot') IS NOT NULL DROP TABLE #Pivot;
--***************************************************************************************
-- Make a Jobname table
--***************************************************************************************
insert into #JobNames (JobName)
select replace(name, ' ', '.') --Replace spaces (they are invalid in XML based pivot lower in the code)
from msdb.dbo.sysjobs
where enabled = #IgnoreDisabledJobs
--WHERE NAME = '<dbname>'
--WHERE NAME like '%<partial dbname>%'
--***************************************************************************************
-- Genereate a Datetime table between StartDT and EndDT with x minute Resolution
--***************************************************************************************
set #DT = #StartDT
WHILE #DT < #EndDT
begin
insert into #Minutes (DT) values(#DT)
set #DT= dateadd(mi, #Resolution, #DT)
end
--***************************************************************************************
-- Create a timeline table by crossjoining the Datetime and Jobnames tables
--***************************************************************************************
select DT, JobName, 0 as Active
into #Timeline
from #Minutes cross join #JobNames
--***************************************************************************************
-- Create the Job Runtime information table
--***************************************************************************************
select replace(name, ' ', '.') as name --Replace spaces (they are invalid in XML based pivot lower in the code)
--,step_id
--,step_name
,CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + ' ' + STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, ':'), 3, 0, ':'), 120) as SDT
,dateadd( s,
((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 ,
CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + ' ' + STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, ':'), 3, 0, ':'), 120)
) as EDT
--,CAST(STUFF(STUFF(REPLACE(STR(run_duration, 6), ' ', '0'), 3, 0, ':'), 6, 0, ':') AS time(0)) AS Duration
,((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 DurationSeconds
into #JobRuntime
FROM msdb.dbo.sysjobs job
left JOIN msdb.dbo.sysjobhistory his
ON his.job_id = job.job_id
where CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + ' ' + STUFF(STUFF(RIGHT('000000' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, ':'), 3, 0, ':'), 120) between #StartDT and #EndDT
and job.name not in ('Database Mirroring Monitor Job', '<dbname>')
and step_id = 0 -- step_id = 0 is the entrite job, step_id > 0 is actual step number
--and ((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 > 1 -- Ignore trivial runtimes
order by SDT
--***************************************************************************************
-- Update the Timeline based on the the Job Runtime information table
--***************************************************************************************
update #Timeline
set Active = 1
from #Timeline inner join #JobRuntime
on JobName = Name
and (
SDT between dt and dateadd(mi, #Resolution - 1, DT) -- Start point (added for Resolution support)
or
EDT between dt and dateadd(mi, #Resolution, DT) -- End point (added for Resolution support)
or
DT between SDT and EDT
)
--***************************************************************************************
-- Delete all jobs from the Timeline that that had no activity
--***************************************************************************************
if #RemoveNonactiveJobs = 1
delete
from #Timeline
where JobName in ( select Jobname
from #Timeline
group by Jobname
having sum(active) = 0 )
--***************************************************************************************
-- Pivot the Timeline table
--***************************************************************************************
DECLARE #Minutes2 AS TABLE(col2set varchar(250) NOT NULL PRIMARY KEY)
DECLARE #cols AS nvarchar(MAX)
create table #Pivot (col1 varchar(250) null, col2 varchar(250) null, col3 int null)
-- col1 = row, col2 = column, col3 = data
insert into #Pivot
select convert(varchar(250), DT, 120), JobName, Active
from #Timeline
-- Make a table with all unique col2 values
INSERT INTO #Minutes2
SELECT DISTINCT col2
FROM #Pivot
SELECT #cols = REPLACE( -- Replace the space in the XML path by a comma
-- ([c1] [c2] [c3] [c4]) -> ([c1],[c2],[c3],[c4])
(
-- Build the IN clause of the PIVOT by concactenating ([c1] [c2] [c3] [c4])
SELECT quotename(col2set) AS [data()]
FROM #Minutes2
ORDER BY col2set
FOR XML PATH ('')
), ' ', ',')
-- Build the pivot statement as a dyanamic sql statement
DECLARE #sql AS nvarchar(MAX)
SET #sql = N'
SELECT col1 as DT,' + #cols + N'
FROM (SELECT col1, col2, col3 FROM #Pivot) AS D
PIVOT(MAX(col3) FOR col2 IN(' + #cols + N')) AS P
order by col1'
--***************************************************************************************
-- Output the Timeline table
--***************************************************************************************
EXEC sp_executesql #sql
--***************************************************************************************
-- Cleanup
--***************************************************************************************
IF OBJECT_ID('tempdb..#Timeline') IS NOT NULL DROP TABLE #Timeline;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
IF OBJECT_ID('tempdb..#Pivot') IS NOT NULL DROP TABLE #Pivot;
The problem occurs in the Pivot the Timeline tablesection of the script as that is not compatable with SQL 2000.
As i have said i have tried almost everything to do this and i am just not experienced enough to solve this problem, i got close but displayed incorrectly.
any help in solving this would be great!!
I managed to answer this myself so thought i would post in case anyone else needs
--
****************************************************************************************
-- This script returns a (graphical) timeline for all SQL jobs for use on SQL Server 2000
--****************************************************************************************
-- Version: 2.0
-- Author: Ryan Wooster
-- Date: 18-6-2013
--****************************************************************************************
set nocount on
declare #Minutes table (DT datetime)
--declare #JobNames table (JobName varchar(255))
declare #DT datetime
declare #StartDT varchar(20)
declare #EndDT varchar(20)
declare #Resolution int
declare #RemoveNonactiveJobs int
declare #IgnoreDisabledJobs int
declare #DSQLT varchar(4000)
declare #DSQL varchar(4000)
declare #Server varchar(20)
--***************************************************************************************
-- Set variables
--***************************************************************************************
set #StartDT = getdate() - 1
set #EndDT = getdate()
set #Resolution = 1 -- Enter the Resolution in minutes
set #RemoveNonactiveJobs = 1
set #IgnoreDisabledJobs = 1
set #Server = 'IGSQ03UK'
--***************************************************************************************
-- Pre-run cleanup (just in case)
--***************************************************************************************
IF OBJECT_ID('tempdb..#Timeline') IS NOT NULL DROP TABLE #Timeline;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
IF OBJECT_ID('tempdb..#Pivot') IS NOT NULL DROP TABLE #Pivot;
IF OBJECT_ID('tempdb..#tblTLine') IS NOT NULL DROP TABLE #tblTLine;
IF OBJECT_ID('tempdb..#tblTasks') IS NOT NULL DROP TABLE #tblTasks;
IF OBJECT_ID('tempdb..#JobNames') IS NOT NULL DROP TABLE #JobNames;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
--***************************************************************************************
--Create Temp Tables for use in Dynamic SQL
--***************************************************************************************
CREATE TABLE #JobNames (JobName varchar(128))
CREATE TABLE #Timeline (DT datetime, JobName varchar(128), Active int)
CREATE TABLE #JobRuntime (name varchar(128), SDT datetime, EDT datetime, DurationSeconds datetime)
--***************************************************************************************
-- Make a Jobname table
--***************************************************************************************
--'+ #IgnoreDisabledJobs +'
SET #DSQLT='
insert into #JobNames (JobName)
select replace(name, '' '', ''.'') --Replace spaces (they are invalid in XML based pivot lower in the code)
from '+ #Server +'.msdb.dbo.sysjobs
where enabled = 1
--WHERE NAME = ''<dbname>''
--WHERE NAME like ''%<partial dbname>%'''
--Print #DSQLT
EXEC (#DSQLT)
--***************************************************************************************
-- Genereate a Datetime table between StartDT and EndDT with x minute Resolution
--***************************************************************************************
set #DT = #StartDT
WHILE #DT < #EndDT
begin
insert into #Minutes (DT) values(#DT)
set #DT= dateadd(mi, #Resolution, #DT)
end
--***************************************************************************************
-- Create a timeline table by crossjoining the Datetime and Jobnames tables
--***************************************************************************************
insert into #Timeline
select DT, JobName, 0 as Active
from #Minutes cross join #JobNames
--***************************************************************************************
-- Create the Job Runtime information table
--***************************************************************************************
SET #DSQL=
'INSERT into #JobRuntime
select replace(name, '' '', ''.'') as name --Replace spaces (they are invalid in XML based pivot lower in the code)
--,step_id
--,step_name
,CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + '' '' + STUFF(STUFF(RIGHT(''000000'' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, '':''), 3, 0, '':''), 120) as SDT
,dateadd( s,
((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 ,
CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + '' '' + STUFF(STUFF(RIGHT(''000000'' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, '':''), 3, 0, '':''), 120)
) as EDT
--,CAST(STUFF(STUFF(REPLACE(STR(run_duration, 6), '' '', ''0''), 3, 0, '':''), 6, 0, '':'') AS time(0)) AS Duration
,((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 DurationSeconds
FROM '+ #Server +'.msdb.dbo.sysjobs job
left JOIN '+ #Server +'.msdb.dbo.sysjobhistory his
ON his.job_id = job.job_id
where CONVERT(DATETIME, CONVERT(CHAR(8), run_date, 112) + '' '' + STUFF(STUFF(RIGHT(''000000'' + CONVERT(VARCHAR(8), run_time), 6), 5, 0, '':''), 3, 0, '':''), 120) between '''+ #StartDT +''' and '''+ #EndDT +'''
and job.name not in (''Database Mirroring Monitor Job'', ''<dbname>'')
and step_id = 0 -- step_id = 0 is the entrite job, step_id > 0 is actual step number
--and ((run_duration/10000)%100 * 3600) + ((run_duration/100)%100 * 60) + run_duration%100 > 1 -- Ignore trivial runtimes
order by SDT'
EXEC (#DSQL)
--***************************************************************************************
-- Update the Timeline based on the the Job Runtime information table
--***************************************************************************************
update #Timeline
set Active = 1
from #Timeline inner join #JobRuntime
on JobName = name
and (
SDT between dt and dateadd(mi, #Resolution - 1, DT) -- Start point (added for Resolution support)
or
EDT between dt and dateadd(mi, #Resolution, DT) -- End point (added for Resolution support)
or
DT between SDT and EDT
)
--***************************************************************************************
-- Delete all jobs from the Timeline that that had no activity
--***************************************************************************************
if #RemoveNonactiveJobs = 1
delete
from #Timeline
where JobName in ( select Jobname
from #Timeline
group by Jobname
having sum(active) = 0 )
--***************************************************************************************
-- Build and Pivot the Timeline table
--***************************************************************************************
create table #Pivot (DT varchar(250) null, Name varchar(250) null, Active int null)
-- col1 = row, col2 = column, col3 = data
insert into #Pivot
select convert(varchar(250), DT, 120), JobName, Active
from #Timeline
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DECLARE #SQL nvarchar(4000)
DECLARE #TaskName nvarchar(100)
SET NOCOUNT ON
CREATE TABLE #tblTLine (
[DT] varchar(200)
)
CREATE TABLE #tblTasks (
[Tasks] varchar(200)
)
INSERT INTO #tblTasks (
[Tasks]
)
select DISTINCT
Name
from #Pivot
INSERT INTO #tblTLine (
[DT]
)
select DISTINCT
[DT]
from #Pivot
ORDER BY DT
--WHERE Active = 1
-- Build Table
DECLARE cur CURSOR FOR
select DISTINCT
[Tasks]
from #tblTasks
OPEN cur
FETCH NEXT FROM cur INTO #TaskName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'ALTER TABLE #tblTLine ADD [' + #TaskName + '] nchar(1) NULL'
EXEC (#SQL)
SET #SQL = ''
SET #SQL = 'UPDATE #tblTLine SET [' + #TaskName + '] = ''0'''
EXEC (#SQL)
FETCH NEXT FROM cur INTO #TaskName
END
CLOSE cur
DEALLOCATE cur
-- Update Table
DECLARE #SQLUpdate nvarchar(4000)
DECLARE #Time nvarchar(100)
DECLARE #Name nvarchar(100)
DECLARE #Active nchar(1)
DECLARE curUpdate CURSOR FOR
SELECT
[DT],
[Name],
[Active]
FROM #Pivot
WHERE Active = 1
OPEN curUpdate
FETCH NEXT FROM curUpdate INTO #Time, #Name, #Active
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQLUpdate = 'UPDATE #tblTLine SET [' + #Name + '] = ''1'' WHERE [DT] = ''' + #Time + ''''
EXEC (#SQLUpdate)
FETCH NEXT FROM curUpdate INTO #Time, #Name, #Active
END
CLOSE curUpdate
DEALLOCATE curUpdate
SET NOCOUNT OFF
--***************************************************************************************
-- Output the Timeline table
--***************************************************************************************
SELECT * FROM #tblTLine
--***************************************************************************************
-- Cleanup
--***************************************************************************************
IF OBJECT_ID('tempdb..#Timeline') IS NOT NULL DROP TABLE #Timeline;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
IF OBJECT_ID('tempdb..#Pivot') IS NOT NULL DROP TABLE #Pivot;
IF OBJECT_ID('tempdb..#tblTLine') IS NOT NULL DROP TABLE #tblTLine;
IF OBJECT_ID('tempdb..#tblTasks') IS NOT NULL DROP TABLE #tblTasks;
IF OBJECT_ID('tempdb..#JobNames') IS NOT NULL DROP TABLE #JobNames;
IF OBJECT_ID('tempdb..#JobRuntime') IS NOT NULL DROP TABLE #JobRuntime;
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
the results look like this but wher the column name says 'Today' I want it to be todays date.
Try this technique:
declare #dt datetime
declare #sql varchar(100)
set #dt = getdate()
set #sql = 'select 1 as [ ' + convert( varchar(25),#dt,120) + ']'
exec (#sql)
In your Case:
declare #dt datetime
declare #sql varchar(100)
set #dt = getdate()
set #sql = 'select 0 as [ ' + convert( varchar(25),#dt,120) + ']'
exec (#sql)
I would return an integer representing a day offset and parse it in the client, failing that you are going to have to use dynamic SQL or do something with the underlying column name itself;;
declare #sql nvarchar(128) = '
select
col1,
col2,
0 as [' + cast(getdate() as nvarchar(32)) + ']
from T'
exec(#sql)
Or
--today
declare #now varchar(32) = cast(getdate() as varchar(32))
--result to temp table
select col1, col2, 0 as [Now] into #T from TheTable
--rename col
exec tempdb..sp_rename '#T.Now', #now, 'COLUMN'
--select
select * from #T