2016-10-10 98 views
0

我有表sdata,它有35列(idnameTRx1TRx2TRx3TRx4,...,TRx30cityscoretotal如何使用循環動態生成列名稱?

我想獲取來自TRx1,...TRx30列中的數據。

我可以在這裏使用循環嗎?

我下面的代碼:

DECLARE @flag INT 
DECLARE @sel varchar(255) 
DECLARE @frm varchar(255) 

SET @flag = 1; 
SET @sel = 'select TRx'; 
SET @frm = ' from sdata'; 

exec(@sel + 

    (WHILE @flag <=5 
     @flag 
    SET @flag = @flag + 1) 

+ @frm) 

什麼錯我在幹嘛?我該如何解決這個問題?

+3

複製/粘貼和更改列名的速度比編寫「while」循環來構建動態查詢的速度快上百萬倍(並且複雜性/容易出錯)。 – Siyual

+1

不要在SQL中使用循環。決不。不要這樣做。 SQL不是循環。 – Hogan

+1

我不明白爲什麼人們討厭while循環。這個'loop'只是爲了產生字符串而沒有任何錯誤....當你通過記錄(即)'RBAR'來處理數據記錄的時候,你不必擔心,但是這個循環完全沒問題。 –

回答

1

只需複製/粘貼列名並將其更改爲正確的名稱,這樣做會容易得多。 但是如果你必須這樣做,我不建議使用循環。這種方法使用了提示表來生成要選擇的列(通過30在這個例子中,列1,但可以改變),然後生成一個動態的SQL語句來執行對SData表:

Declare @From Int = 1, 
     @To  Int = 30, 
     @Sql NVarchar (Max) 

Declare @Columns Table (Col Varchar (255)) 

;With Nums As 
(
    Select * 
    From (Values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) As V(N) 
), Tally As 
(
    Select Row_Number() Over (Order By (Select Null)) As N 
    From  Nums A --10 
    Cross Join Nums B --100 
    Cross Join Nums C --1000 
) 
Insert @Columns 
Select 'TRx' + Cast(N As Varchar) 
From Tally 
Where N Between @From And @To 

;With Cols As 
(
    Select (
       Select QuoteName(Col) + ',' As [text()] 
       From @Columns 
       For Xml Path ('') 
      ) As Cols 
) 
Select @Sql = 'Select ' + Left(Cols, Len(Cols) - 1) + ' From SData' 
From Cols 

--Select @Sql 
Execute (@Sql) 

注意:--Select @Sql部分用於在執行生成的查詢之前預覽它。

+0

謝謝。代碼運行完美,但很難理解,因爲我是新的SQL。 – Japs

0

您可以選擇列名這樣的:

SELECT column_name 
FROM information_schema.columns 
WHERE table_name = 'my name here' 
3

如果你的表名是SDATA,此代碼應爲你工作:

-- Grab the names of all the remaining columns 
DECLARE @sql nvarchar(MAX); 
DECLARE @columns nvarchar(MAX); 
SELECT @columns = STUFF ((SELECT N'], [' + name 
      FROM sys.columns 
      WHERE object_id = (select top 1 object_id FROM sys.objects where name = 'sdata') 
      AND name LIKE 'TRx%' -- To limit which columns 
      ORDER BY column_id 
      FOR XML PATH('')), 1, 2, '') + ']'; 
PRINT @columns 
SELECT @sql = 'SELECT ' + @columns + ' FROM sdata'; 
PRINT @sql; 
EXEC (@sql); 

注意我包括PRINT語句所以你可以看到這是怎麼回事。您可能想在測試時註釋掉EXEC。

+0

使用'QUOTENAME'來轉義列更健壯(儘管如果你在你的列名中使用''',你是個受虐狂者)。 'SELECT QUOTENAME(name)+',''並用'REVERSE(STUFF(REVERSE((...)),1,1,''))''去掉最後的''''。 –

+0

如果我們只想要這些列,就缺少'AND LIKE'TRx%''。 (這種方法的優勢之一是能夠根據我們喜歡的任何標準從實際列中選擇和選擇,因此您可以展示這一點。) –

+0

正確...我想提供更通用的模板這可以定製,並儘可能「清晰」。我會更新片段,以便更清楚。謝謝。 – pmbAustin