SQL Server 2008 ALTER TABLE добавить столбец с конкретным столбцом - PullRequest
0 голосов
/ 28 февраля 2012

Можно ли как-нибудь добавить столбец в таблицу, но я хочу, чтобы заголовок был датой, и каждый новый добавленный столбец будет иметь заголовок столбца на следующий день, следовательно,

SET @date1 = @date1 + 1

Я хочу, чтобы таблица выглядела следующим образом: где дата сверху - это новый столбец для каждого дня цикла, в котором выполняется цикл:

StoreID StoreName     02/01/12    03/01/12    04/01/12
1234  Coles1         7512       8574        
1235  Coles2         7210       8441
1236  Coles3         4845       5448

Когда я запускаю сценарий, я получаю следующие сообщения об ошибках:

Сообщение 170, уровень 15, состояние 1, строка 1
строка 1: неправильный синтаксис рядом с'@Column'.
Сообщение 170, уровень 15, состояние 1, строка 1
строка 1: Неверный синтаксис рядом с'@Column'.

Вот мой сценарий:

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 

Ответы [ 3 ]

2 голосов
/ 28 февраля 2012

Вы не можете сделать это без динамического SQL.Вот запрос, который даст вам желаемый результат.Мы с радостью раскомментируем бит --INTO #t, однако неясно, что вы хотите сделать с таблицей #tevent, за исключением этого (если вы сообщите нам конечный результат, вместо «Я хочу добавить имя столбца как @столбец, может быть, мы можем помочь с этим тоже.) Чтобы продолжить ссылаться на эту таблицу #t, вам нужно будет продолжать использовать код в той же области видимости - то есть более динамический SQL, который выполняется в рамках того же самого вызова sp_executesql.

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;
0 голосов
/ 28 февраля 2012

Есть две вещи, которые вам нужно сделать, чтобы выполнить этот код ...

  1. Создать динамический sql, используя SP_ExecuteSQl
  2. , вам нужно сделать вашу временную таблицу Gobalпотому что, когда вы создаете личную временную таблицу, она остается в области действия только dyanic sql sp

. Посмотрите на приведенный ниже код, который я обновил, обязательно решите вашу проблему

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
0 голосов
/ 28 февраля 2012

Мне кажется, проблема в том, что вы не можете использовать переменную для определения имени столбца.

Я использовал для проверки часть вашего кода.Эта первая часть была выполнена нормально.

DECLARE @date1 datetime
DECLARE @Column varchar(8)
SET @date1 = '02 Jan 2012'
SET @Column = CONVERT(VARCHAR(8), @date1, 3)
select @Column 

Но когда я добавил оператор CREATE TABLE и выполнил все его сразу, я получил ту же ошибку, что и вы.

CREATE TABLE #vl_temp_trans
(StoreID INT,
StoreName VARCHAR(100),
@Column MONEY)                  ----> column name to be date "@Column)

ToДля этого вам нужно будет создать операторы CREATE TABLE и ALTER TABLE в виде строки, а затем выполнить их, используя EXECUTE или sp_executesql . поиск "dynamic sql" также даст вам статью, в которой это тоже описано.

...