变量作为列名SQL Server

时间:2018-12-04 16:55:37

标签: sql-server

我想知道,是否存在一种创建具有可变列名的CURSOR的方法

示例:

我有这张桌子:

Result Table

text的翻译图片

ID | TEST1 | TEST2 | TEST3
7      1       3       1
8      2       3       4
9      3       4       5
10     3       3       1
11     2       3       4
12     3       4       5
13     1       3       1
14     2       3       4
15     3       4       5

SQL代码:

DECLARE
   @count int,
   @columnX varchar(5),
   @aux2previous int,
   @aux2 int,
   @aux1 int,
   @columnXResult int,
   @id int;

SET @aux2previous = 0;
SET @count = 1;

SET @columnX = 'test' + count;
DECLARE cursor1 CURSOR FOR
    SELECT ID, @columnX FROM table

OPEN cursor1 

FETCH NEXT FROM cursor1 INTO @id,@columnXResult

...

SET @aux1 = @columnXResult+ @aux2previous
SET @aux2 = @aux2previous + 1                               
SET @string = 'SXW_'+@columnX+'_'+@aux1+'<>'+@aux2

INSERT INTO tblAuxiliary VALUES(@aux1,@aux2,@string)

SET @count = @count + 1;
SET @aux2previous = @aux2

...

Result Table Auxiliary (what i need)

text的翻译图片

在我的第一个表中的Foreach行中,我在这里有一个新行:

对于Test1列

AUX1 | AUX2 | STRING
 1      1      SXW_Test1_1<>1
 3      2      SXW_Test1_3<>2

对于Test2列

AUX1 | AUX2 | STRING
 3      1      SXW_Test2_3<>1
 6      4      SXW_Test2_6<>4

对于Test3列

AUX1 | AUX2 | STRING
 1      1      SXW_Test3_1<>1
 5      2      SXW_Test3_5<>2

当我使用@columnX时

SELECT ID, @columnX FROM table

我收到此错误:

  

将varchar值'test1'转换为数据类型int时转换失败

我看到类似@sql = 'select '+@columnX ...,的内容,但是我需要执行它,而我无法使用游标执行此操作。

3 个答案:

答案 0 :(得分:1)

这是如何使用动态sql和游标的示例:

create table test (
  t1 int not null,
  t2 varchar(10) not null
)

declare @query varchar(1000)

select @query = '
   declare @column int

   declare query cursor for
     select t'+cast(1 as varchar(1))+' from test

    open query
    fetch next from query into @column
    while(@@FETCH_STATUS=0)
    begin
       select @column

     fetch next from query into @column
    end
    close query
    deallocate query
'
exec (@query)

答案 1 :(得分:0)

除非使用动态SQL,否则无法用可变的列名称创建游标:建立SQL代码字符串并使用EXEC sp_executesql运行它。这很麻烦而且很难解决,但是您可以通过反复试验来做到这一点(最好在开发系统上,而不是在生产系统上)。

FWIW,我认为上面的一些评论有些苛刻,因为他们忘记了开始涉足该领域的感觉:您做得很好。光标 经常被Web开发人员滥用,他们会从程序角度进行思考,而不是“基于集合”,但是我仍然偶尔在有意义的地方使用它们(或者更简单)。如果您愿意,您可以发布一个新问题,其中包含有关您要完成的工作的更多详细信息,并询问“我如何摆脱此光标”。但是,如果光标的性能还可以,请不必担心。

HTH!

答案 2 :(得分:0)

检查一下。

DECLARE @table TABLE(ID INT,test1 INT,test2 INT,test3 INT)

INSERT INTO @TABLE VALUES
(7,1,3,1),(8,2,3,4),(9,3,4,5),(10,3,3,1),
(11,2,3,4),(12,3,4,5),(13,1,3,1),(14,2,3,4),
(15,3,4,5)

SELECT top 2
t.test1 AUX1,(t.test1+T.prev_test1) AUX2,concat('SXW_Test1_',t.test1,'<>',(t.test1+T.prev_test1)) as string FROM 
(
SELECT test1,
LAG(test1,1,0) OVER (ORDER BY ID) prev_test1
 FROM @table
) t

union all

SELECT top 2
t.test2 AUX1,(t.test2+T.prev_test2) AUX2,concat('SXW_Test2_',t.test2,'<>',(t.test2+T.prev_test2)) as string FROM 
(
SELECT test2,
LAG(test2,1,0) OVER (ORDER BY ID) prev_test2
 FROM @table
) t

union all

SELECT top 2
t.test3 AUX1,(t.test3+T.prev_test3) AUX2,concat('SXW_test3_',t.test3,'<>',(t.test3+T.prev_test3)) as string FROM 
(
SELECT test3,
LAG(test3,1,0) OVER (ORDER BY ID) prev_test3
 FROM @table
) t

enter image description here