我想使用动态表名和动态列名在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
答案 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'