HL8
HL8

Reputation: 1419

SQL Server 2008 ALTER TABLE add column with specific column

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 

Upvotes: 1

Views: 10389

Answers (3)

Sanjay Goswami
Sanjay Goswami

Reputation: 1386

There is two things you need to do to execute this code...

  1. Create dynamic sql make use of SP_ExecuteSQl
  2. 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

Upvotes: 0

Aaron Bertrand
Aaron Bertrand

Reputation: 280570

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;

Upvotes: 2

Adam Porad
Adam Porad

Reputation: 14471

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.

Upvotes: 0

Related Questions