SQL SERVER動態列名 數據表列值轉換爲逗號分隔字符串

在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
Source Code

 

另外一份數據:函數

 

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
Source Code

 

一切準備完畢,開始實現,建立一張臨時表,將用來存儲實現的數據。post

 

IF OBJECT_ID('tempdb..#Temp_Result_Rpt') IS NOT NULL DROP TABLE #Temp_Result_Rpt  
CREATE TABLE #Temp_Result_Rpt
(   
    [Name] NVARCHAR(40) 
)        
Source Code

 

下面是處理動態列,把[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
Source Code

 

上面有一個自定義函數[dbo].[usp_TableColumnValueToCommaDelimitedString],它的實現方法,能夠參考這裏《數據表列值轉換爲逗號分隔字符串http://www.javashuo.com/article/p-yxqwruzx-ge.htmlspa

 

定義一個變量,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 +'')
Source Code

 

獲得空表格,最後的動做,是須要把原始數據合併至這張臨時表中。

有記錄的,進行更新,沒有記錄的,插入新記錄:

 

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 +'')
Source Code

 

完成!

其中使用了不少動態SQL。

相關文章
相關標籤/搜索