SQL SELECT动态列名称

时间:2018-11-22 11:10:51

标签: sql sql-server dynamic

在MS SQL中有什么方法可以创建像这样的动态选择查询吗? :

    DECLARE @cnt INT = 1
    DECLARE @value NVARCHAR(25)
    DECLARE @query  AS NVARCHAR(MAX)
    DECLARE @part NVARCHAR(25) = 'W11282173'

            WHILE @cnt <= 10
                BEGIN
                       Set @query = N'SELECT Check'+str(@cnt)+ N' from udtSmartPlastic where Partnumber ='+@part
                       exec sp_executesql @query;
                       SET @cnt = @cnt + 1
                END

我有这样的桌子:

enter image description here

这个想法是运行一个while循环,一张一张地从表(所有10个表)中获取特定值,并将它们设置为某个组件的值。

如果有另一种更简便,更复杂的方法来做到这一点,请告诉我。

扩展代码:

 DECLARE @cnt INT = 1
 DECLARE @value NVARCHAR(25)
 DECLARE @query  AS NVARCHAR(MAX)
 DECLARE @part NVARCHAR(25) = 'W11282173'
                        WHILE @cnt <= 10
                            BEGIN
                              set @query = N'SELECT Check'+str(@cnt)+ N' from udtSmartPlastic where Partnumber ='+@part
                              exec sp_executesql @query;
                              --SELECT Check+str(1) from udtSmartPlastic where PartNumber = 'W11282173'
                              INSERT INTO @TblReturn VALUES ('txtCheck'+str(@cnt), 'Property', '<property Value='+@value+'/>')
                              SET @cnt = @cnt + 1
                            END

我必须从Columns中获取值并分配标签Check1..2..3的值(基本上将其重命名)

enter image description here

1 个答案:

答案 0 :(得分:0)

这复制了您拥有的SQL,但是,我真的不明白为什么为什么要这样做:

DECLARE @SQL nvarchar(MAX);
DECLARE @Part nvarchar(25) = 'W11282173'

WITH Tally AS (
    SELECT I
    FROM (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) V(I))
SELECT @SQL = STUFF((SELECT NCHAR(10) + N'SELECT ' + QUOTENAME(N'CHECK' + CONVERT(nvarchar(2),T.I)) + N' FROM udtSmartPlastic WHERE Partnumber = @dPart;'
                     FROM Tally T
                     FOR XML PATH(N'')),1,1,N'');

PRINT @SQL;
EXEC sys.sp_executesql @SQL, N'@dPart nvarchar(25)',@dPart = @Part;

请注意,我已将您的查询从一个开放查询更改为一个注入参数查询。注射离您的朋友很远,您应该尽一切努力使某人无法做到。

编辑:关于规范化数据;您可以通过以下方法轻松实现这一目标:

SELECT SP.PartNumber,
   CHOOSE(T.I,Check1,Check2,Check3,Check4,Check5,Check6,Check7,Check8,Check9,Check10) AS CheckValue
--INTO udtSmartPlasticn
FROM udtSmartPlastic SP
     CROSS APPLY (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) T(I);