经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MS SQL Server » 查看文章
SQL SERVER动态列名
来源:cnblogs  作者:Insus.NET  时间:2019/5/31 8:49:18  对本文有异议

在ms sql server实现动态呈现列的方法很多。下面Insus.NET解决也算是另外一种参考。

如:

 

准备实现功能的数据:

 

  1. CREATE TABLE [dbo].[Timing] ([When] NVARCHAR(10) NOT NULL PRIMARY KEY)
  2. INSERT INTO [dbo].[Timing] VALUES
  3. (N'周五.晚上'),
  4. (N'周六.中午'),
  5. (N'周六.晚上'),
  6. (N'周日.中午'),
  7. (N'周日.晚上')
  8. GO
  9. SELECT [When] FROM [dbo].[Timing]
  10. GO
Source Code

 

另一份数据:

 

  1. CREATE TABLE [dbo].[Schedule] (
  2. [ID] INT IDENTITY(1,1) PRIMARY KEY,
  3. [Name] NVARCHAR(40),
  4. [When] NVARCHAR(10) FOREIGN KEY REFERENCES [dbo].[Timing]([When])
  5. )
  6. GO
  7.  
  8. INSERT INTO [dbo].[Schedule] ([NAME],[When]) VALUES
  9. (N'EMP-00201',N'周六.晚上'),(N'EMP-00201',N'周日.中午'),
  10. (N'EMP-00202',N'周六.中午'),(N'EMP-00202',N'周六.晚上'),(N'EMP-00202',N'周日.中午'),
  11. (N'EMP-00207',N'周五.晚上'),(N'EMP-00207',N'周六.中午'),(N'EMP-00207',N'周日.中午'),
  12. (N'EMP-00209',N'周五.晚上'),(N'EMP-00209',N'周六.中午'),(N'EMP-00209',N'周六.晚上')
  13. GO
  14.  
  15. SELECT [NAME],[When] FROM [dbo].[Schedule]
  16. GO
Source Code

 

一切准备完毕,开始实现,创建一张临时表,将用来存储实现的数据。

 

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

 

下面是处理动态列,把[dbo].[Timing]的数据转换为列,把它们处理为[xxx],[yyy],[zzz]...逗号串连在一起。

 

  1. DECLARE @Comma_Delimited_Column_Names NVARCHAR(MAX)
  2. EXECUTE [dbo].[usp_TableColumnValueToCommaDelimitedString] '[Timing]','[When]',@Comma_Delimited_Column_Names OUTPUT
  3. SELECT @Comma_Delimited_Column_Names
Source Code

 

上面有一个自定义函数[dbo].[usp_TableColumnValueToCommaDelimitedString],它的实现方法,可以参考这里《数据表列值转换为逗号分隔字符串https://www.cnblogs.com/insus/p/10848578.html

 

定义一个变量,

  1. DECLARE @TABLE_NAME SYSNAME = N'#Temp_Result_Rpt'

给变量赋的值就是上面的创建的临时表名。

这个变量,将在下面的代码中使用得到。

 

接下来,我们需要把上面得到的动态列名,修改至临时表中去:

  1. DECLARE @Source NVARCHAR(MAX) = @Comma_Delimited_Column_Names + N','
  2. WHILE CHARINDEX(',', @Source) > 0
  3. BEGIN
  4. DECLARE @DATA_TYPE SYSNAME = N'NVARCHAR(10)'
  5. DECLARE @COLUMN_NAME SYSNAME = SUBSTRING(@Source, 0, CHARINDEX(',', @Source))
  6. SET @Source = LTRIM(RTRIM(SUBSTRING(@Source, CHARINDEX(',', @Source) + 1, LEN(@Source))))
  7. EXECUTE('ALTER TABLE '+ @TABLE_NAME +' ADD '+ @COLUMN_NAME +' '+ @DATA_TYPE +' DEFAULT(N'''')')
  8. END
  9.  
  10. EXECUTE('SELECT [Name],'+ @Comma_Delimited_Column_Names +' FROM '+ @TABLE_NAME +'')
Source Code

 

得到空表格,最后的动作,是需要把原始数据合并至这张临时表中。

有记录的,进行更新,没有记录的,插入新记录:

 

  1. DECLARE @r INT = 1,@rs INT = 0
  2. SELECT @rs = MAX([ID]) FROM [dbo].[Schedule]
  3.  
  4. WHILE @r <= @rs
  5. BEGIN
  6. DECLARE @Name nvarchar(40)
  7. SELECT @COLUMN_NAME = [When],@Name = [Name] FROM [dbo].[Schedule] WHERE [ID] = @r
  8. EXECUTE('
  9. IF EXISTS(SELECT TOP 1 1 FROM '+ @TABLE_NAME +' WHERE [NAME] = N'''+ @NAME +''')
  10. UPDATE '+ @TABLE_NAME +' SET ['+ @COLUMN_NAME +'] = N''?'' WHERE [NAME] = N'''+ @NAME +'''
  11. ELSE
  12. INSERT INTO '+ @TABLE_NAME +' ([NAME],['+ @COLUMN_NAME +']) VALUES(N'''+ @NAME +''',N''?'')
  13. ')
  14. SET @r = @r + 1
  15. END
  16.  
  17.  
  18. EXECUTE('SELECT [Name],'+ @Comma_Delimited_Column_Names +' FROM '+ @TABLE_NAME +'')
Source Code

 

完成!

其中使用了很多动态SQL。

 

原文链接:http://www.cnblogs.com/insus/p/10947429.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号