在SQL Server 2008中创建动态表名称和表列?

时间:2015-10-24 07:02:52

标签: sql-server sql-server-2008

我想使用动态表名和动态列名在SQL Server中创建动态表。例如:

表名:01-02-2015

列名:

 Id 01 02 03.... 28

当我创建一个临时表时,我想创建一个真正的表,然后我使用下面这样的脚本,当执行错误发生时:

  

Msg 102,Level 15,State 1,Line 1
  ' .01'。

附近的语法不正确

代码:

DECLARE @DynamicSQL as NVARCHAR(max),@TempTableName as nvarchar(max)
DECLARE @TimeSheetDate as DateTime
DECLARE @startDate AS DATETIME --Cursor Local Variables
DECLARE @endDate AS DATETIME

SET @TimeSheetDate = '2015-2-15'
SET @startDate = DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate), 0) -- the first day of month
SET @endDate = DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate) + 1, 0))-- the last day of month
SET @TempTableName = @startDate -- the first day of month

SET @DynamicSQL='CREATE TABLE dbo.'+ quotename(@TempTableName, '[') + '(Id int identity(1,1) not null primary key);';

WHILE (@startDate <= @endDate)
BEGIN
        --DECLARE @DynamicSQL VARCHAR(500)

        BEGIN
            SET @DynamicSQL = 'ALTER TABLE dbo.' + @TempTableName  + 
                              ' ADD ['+ CONVERT(VARCHAR(2), @startDate, 105) + '] NVARCHAR(max) NULL'
            EXECUTE (@DynamicSQL)
        END

        SET @startDate = DateADD(dd, 1, @startDate)

        IF @startDate - 1 = @endDate
            BREAK;
    END

    exec (@DynamicSQL);

如果我使用此脚本创建临时表,则可以:

DECLARE @TempTableName as nvarchar(100)
DECLARE @TimeSheetDate as DateTime
DECLARE @startDate AS DATETIME --Cursor Local Variables
DECLARE @endDate AS DATETIME

SET @TimeSheetDate = '2015-2-15'
SET @startDate = DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate), 0)
SET @endDate = DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate) + 1, 0))
SET @TempTableName = DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate), 0)

if exists (select * from tempdb.dbo.sysobjects o where o.xtype in ('U') and o.id = object_id(N'tempdb..#@TempTableName'))
    DROP TABLE #@TempTableName

CREATE TABLE #@TempTableName(Id int identity(1,1) not null primary key) -- Creating Temp Table

    -- Loop to add columns to temp table
    WHILE (@startDate <=@endDate)
    BEGIN
        DECLARE @DynamicSQL VARCHAR(500)

        BEGIN
            SET @DynamicSQL = 'ALTER TABLE #@TempTableName ADD ['+ CONVERT(VARCHAR(2),@startDate,105) +'] NVARCHAR(100) NULL'
            EXECUTE (@DynamicSQL)
        END

        SET @startDate = DateADD(dd,1,@startDate)
        IF @startDate-1 = @endDate
            BREAK;
    END

    SELECT * FROM #@TempTableName

2 个答案:

答案 0 :(得分:1)

这符合我的期望:

ALTER PROCEDURE [dbo].[proc_InsertTimeSheetInit] 
    @TimeSheetDate as DateTime  
AS
BEGIN

         DECLARE @DynamicSQL as NVARCHAR(255)
        DECLARE @TableName as nvarchar(255) 
        DECLARE @startDate AS DATETIME 
        DECLARE @endDate AS DATETIME
        DECLARE @dropSQL as NVARCHAR(255)
        SET @startDate = DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate), 0) -- the first day of month
        SET @endDate = DATEADD (dd, -1, DATEADD(mm, DATEDIFF(mm, 0, @TimeSheetDate) + 1, 0))-- the last day of month
        SET  @TableName ='TS'+convert(nvarchar(2), datepart(mm, @TimeSheetDate)) + convert(nvarchar(4), datepart(yyyy, @TimeSheetDate))
        IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].['+ @TableName+ ']') AND type in (N'U'))
        SELECT @dropSQL = 'DROP TABLE dbo.' + QUOTENAME(@TableName) + '';
        exec (@dropSQL)
        SET @DynamicSQL = 'create table [dbo].[' + @TableName + ']([Id] [int] IDENTITY(1,1) NOT NULL,CONSTRAINT PK_'+@TableName+' PRIMARY KEY CLUSTERED (Id))'
        exec (@DynamicSQL) 
        WHILE (@startDate <= @endDate)
        BEGIN

                BEGIN
                    SET @DynamicSQL = 'ALTER TABLE [dbo].[' + @TableName  + '] ADD ['+ CONVERT(VARCHAR(2), @startDate, 105) + '] NVARCHAR(50) NULL'
                    EXECUTE (@DynamicSQL)
                END

                SET @startDate = DateADD(dd, 1, @startDate)

                IF @startDate - 1 = @endDate
                    BREAK;
            END 
END

答案 1 :(得分:0)

问题出在你的alter table语句中。

更改

 SET @DynamicSQL = 'ALTER TABLE dbo.' + @TempTableName  + 
                              ' ADD ['+ CONVERT(VARCHAR(2), @startDate, 105) + '] NVARCHAR(max) NULL'

 SET @DynamicSQL = 'ALTER TABLE dbo.' + quotename(@TempTableName, '[')  + 
                              ' ADD ['+ CONVERT(VARCHAR(2), @startDate, 105) + '] NVARCHAR(max) NULL'