删除未使用的(生成的)列

时间:2017-12-11 12:58:30

标签: sql-server dynamic cursor

我正在尝试拆分名称值,然后分析它们。为此,我在T-SQL中生成15列,然后使用UDF(https://social.technet.microsoft.com/wiki/contents/articles/26937.t-sql-splitting-a-string-into-multiple-columns.aspx)将列“值”拆分为新列(使用空格作为分隔符)。到目前为止,我按照预期得到了以下结果,非常好......

id|value  |col_1|col_2|col_3|col_4|col_5|col_6|col_7|col_8|col_9|col_10|col_11|col_12|col_13|col_14|col_15
1 |xxx    |x    |x    |x    |     |     |     |     |     |     |      |      |      |      |      |     
2 |x      |x    |     |     |     |     |     |     |     |     |      |      |      |      |      |
3 |xxxxxxx|x    |x    |x    |x    |x    |x    |x    |     |     |      |      |      |      |      |
4 |xxxx   |x    |x    |x    |x    |     |     |     |     |     |      |      |      |      |      |

对我的解决方案感到满意我开始使用代码来真正分析单独的部分。然而,我的同事提出了一个小的无意义的说明,他说应该删除未使用的列。而且因为我被任命帮助同事而不是告诉他们他们的问题多么愚蠢,我说我会调查它。

问题是我的自我不允许我使用15条硬编码线。我真的很想用光标来做这个,所以如果以后需要解析更长的字符串(btw实际上可以假设),代码会继续工作。我在游标中使用数字来创建列名。然后我认为最好使用#1中的select 1来查看len(column_name)' - 查询列是否在使用中。但是现在我很难创建包含创建的column_name的动态sql。这是一个问题,因为我发现空的时候需要相同的column_name来实际删除它。

while @count < @max_nr_columns
begin
set @colname = 'part' + convert(varchar(255), (@count + 1))
declare @max_col_real nvarchar(4000)-- = N'max_col_real_is_empty'
declare @mc int = 0
exec('sp_executesql (select 1 from #1 where ' + @colname + ' is not null), N''@max_col_real nvarchar(4000) output'', @max_col_real output')
set @max_col_real = (@sql)
set @count = @count + 1
end
print @max_col_real

它抛出一个关于逗号的错误,这意味着问题存在于exec-line中。有人能指出我正确的方向去除第8-15列吗?或者告诉我上面代码中我做错了什么?

我正在使用SQL2014,但希望在2008年之前保持向下兼容。

1 个答案:

答案 0 :(得分:1)

您可以转动以抑制空值。自2008年以来,Pivot,Stuff和FOR XML应该可用。

所以例子可能是

使用DYNAMIC UNPIVOT进行SQL代码更新

   Create table #temp (id int, value nvarchar(50),col_1 nvarchar(50),col_2 nvarchar(50),col_3 nvarchar(50),col_4 nvarchar(50),col_5 nvarchar(50),col_6 nvarchar(50),col_7 nvarchar(50),col_8 nvarchar(50),col_9 nvarchar(50))

insert into #temp
values


(1 ,'xxx'    ,'x','x','x',null,null,null,null,null,null),    
(2 ,'x'      ,'x',null,null,null,null,null,null,null,null), 
(3 ,'xxxxxxx','x','x','x','x','x','x','x',null,null),  
(4 ,'xxxx'   ,'x','x','x','x',null,null,null,null,null) 




declare @gruppe nvarchar(max)
      declare @gruppeSql nvarchar(max)
      declare @SQL nvarchar(max)
      DECLARE myCustomers CURSOR FOR

Select [Name] from tempdb.sys.columns where object_id = object_id('tempdb..#temp') 
and [name] like 'col%' 

      set @gruppeSql = ''
      OPEN myCustomers
       FETCH NEXT FROM myCustomers INTO @gruppe
      IF (@@FETCH_STATUS>=0)
      BEGIN
      SET @gruppeSql = @gruppeSql +'[' +@gruppe+']'
      FETCH NEXT FROM myCustomers INTO @gruppe
       END
       WHILE (@@FETCH_STATUS<>-1)
       BEGIN
       IF (@@FETCH_STATUS<>-2)

       SET @gruppeSql = @gruppeSql  + ',[' +@gruppe+']'
       FETCH NEXT FROM myCustomers INTO @gruppe
       END
       CLOSE myCustomers
       DEALLOCATE myCustomers 

      SET @gruppeSql = replace(@gruppesql,'''','')
      print @gruppeSql
      --select @gruppeSql
       SET @SQL = '


        SELECT distinct Pets = ''Select'' + STUFF((SELECT N'', '' + cols 
  FROM (select distinct cols from #temp a

UNPIVOT (Rowno for Cols in('+@gruppeSql+')) as pvy ) AS p2

   FOR XML PATH(N'''')), 1, 2, N'' '')'




      print @sql
      exec(@sql)
      drop table #temp