在ms sql server實現動態呈現列的方法不少。下面Insus.NET解決也算是另一種參考。html
如:sql
準備實現功能的數據:ide
CREATE TABLE [dbo].[Timing] ([When] NVARCHAR(10) NOT NULL PRIMARY KEY) INSERT INTO [dbo].[Timing] VALUES (N'週五.晚上'), (N'週六.中午'), (N'週六.晚上'), (N'週日.中午'), (N'週日.晚上') GO SELECT [When] FROM [dbo].[Timing] GO
另外一份數據:函數
CREATE TABLE [dbo].[Schedule] ( [ID] INT IDENTITY(1,1) PRIMARY KEY, [Name] NVARCHAR(40), [When] NVARCHAR(10) FOREIGN KEY REFERENCES [dbo].[Timing]([When]) ) GO INSERT INTO [dbo].[Schedule] ([NAME],[When]) VALUES (N'EMP-00201',N'週六.晚上'),(N'EMP-00201',N'週日.中午'), (N'EMP-00202',N'週六.中午'),(N'EMP-00202',N'週六.晚上'),(N'EMP-00202',N'週日.中午'), (N'EMP-00207',N'週五.晚上'),(N'EMP-00207',N'週六.中午'),(N'EMP-00207',N'週日.中午'), (N'EMP-00209',N'週五.晚上'),(N'EMP-00209',N'週六.中午'),(N'EMP-00209',N'週六.晚上') GO SELECT [NAME],[When] FROM [dbo].[Schedule] GO
一切準備完畢,開始實現,建立一張臨時表,將用來存儲實現的數據。post
IF OBJECT_ID('tempdb..#Temp_Result_Rpt') IS NOT NULL DROP TABLE #Temp_Result_Rpt CREATE TABLE #Temp_Result_Rpt ( [Name] NVARCHAR(40) )
下面是處理動態列,把[dbo].[Timing]的數據轉換爲列,把它們處理爲[xxx],[yyy],[zzz]...逗號串連在一塊兒。url
DECLARE @Comma_Delimited_Column_Names NVARCHAR(MAX) EXECUTE [dbo].[usp_TableColumnValueToCommaDelimitedString] '[Timing]','[When]',@Comma_Delimited_Column_Names OUTPUT SELECT @Comma_Delimited_Column_Names
上面有一個自定義函數[dbo].[usp_TableColumnValueToCommaDelimitedString],它的實現方法,能夠參考這裏《數據表列值轉換爲逗號分隔字符串》http://www.javashuo.com/article/p-yxqwruzx-ge.html:spa
定義一個變量,code
DECLARE @TABLE_NAME SYSNAME = N'#Temp_Result_Rpt'
給變量賦的值就是上面的建立的臨時表名。server
這個變量,將在下面的代碼中使用獲得。htm
接下來,咱們須要把上面獲得的動態列名,修改至臨時表中去:
DECLARE @Source NVARCHAR(MAX) = @Comma_Delimited_Column_Names + N',' WHILE CHARINDEX(',', @Source) > 0 BEGIN DECLARE @DATA_TYPE SYSNAME = N'NVARCHAR(10)' DECLARE @COLUMN_NAME SYSNAME = SUBSTRING(@Source, 0, CHARINDEX(',', @Source)) SET @Source = LTRIM(RTRIM(SUBSTRING(@Source, CHARINDEX(',', @Source) + 1, LEN(@Source)))) EXECUTE('ALTER TABLE '+ @TABLE_NAME +' ADD '+ @COLUMN_NAME +' '+ @DATA_TYPE +' DEFAULT(N'''')') END EXECUTE('SELECT [Name],'+ @Comma_Delimited_Column_Names +' FROM '+ @TABLE_NAME +'')
獲得空表格,最後的動做,是須要把原始數據合併至這張臨時表中。
有記錄的,進行更新,沒有記錄的,插入新記錄:
DECLARE @r INT = 1,@rs INT = 0 SELECT @rs = MAX([ID]) FROM [dbo].[Schedule] WHILE @r <= @rs BEGIN DECLARE @Name nvarchar(40) SELECT @COLUMN_NAME = [When],@Name = [Name] FROM [dbo].[Schedule] WHERE [ID] = @r EXECUTE(' IF EXISTS(SELECT TOP 1 1 FROM '+ @TABLE_NAME +' WHERE [NAME] = N'''+ @NAME +''') UPDATE '+ @TABLE_NAME +' SET ['+ @COLUMN_NAME +'] = N''✔'' WHERE [NAME] = N'''+ @NAME +''' ELSE INSERT INTO '+ @TABLE_NAME +' ([NAME],['+ @COLUMN_NAME +']) VALUES(N'''+ @NAME +''',N''✔'') ') SET @r = @r + 1 END EXECUTE('SELECT [Name],'+ @Comma_Delimited_Column_Names +' FROM '+ @TABLE_NAME +'')
完成!
其中使用了不少動態SQL。