2016-08-11 3 views
0

Обеспечение динамических раздельных значений для каждого столбца. Количество значений в @column_name1 и @aliasing_val может изменяться согласно требованиям, поэтому, пожалуйста, предоставьте решение, которое может работать для любого количества значений в @column_name1 и @aliasing_val.Динамическое сглаживание имен столбцов в SQL Server

Declare @table_name1  NVARCHAR(250) = 'table1', 
    @column_name1   NVARCHAR(250) = 't1col1,t1col2,t1col3', 
    @aliasing_val   NVARCHAR(250) = 'c1,c2,c3', 
    @SQLString    nvarchar(max), 
    @SQLString2    nvarchar(max) 


If ((@table_name1 IS NOT NULL AND LEN(@table_name1) !=0) 
AND (@column_name1 IS NOT NULL AND LEN(@column_name1) !=0)) 
BEGIN 
set @SQLString2 = 'SELECT ' 

Select @SQLString2 = @SQLString2 + 
QUOTENAME(split.a.value('.', 'VARCHAR(100)')) + ' As '+aliasing_val+', 
' 
FROM (SELECT Cast ('<M>' + Replace(@column_name1, ',', '</M><M>')+ '</M>' AS XML) AS Data) AS A 
CROSS apply data.nodes ('/M') AS Split(a); 

Set @SQLString2 = LEFT(@SQLString2, LEN(@SQLString2) - 3) 

END 

print @SQLString2 

Токовый выход:

SELECT [t1col1] As c1,c2,c3, 
[t1col2] As c1,c2,c3, 
[t1col3] As c1,c2,c3 

Ожидаемый результат

SELECT [t1col1] As c1, 
[t1col2] As c2, 
[t1col3] As c3 

ответ

1

Вы находитесь на правильном пути. Единственное, что вам нужно сделать, это два отдельных оператора выбора для @column_name и @aliasing_val и присоединиться к ней, используя ROW_NUMBER() функцию, и вы получили то, что вы ожидаете - Попробуйте

IF ((@table_name1 IS NOT NULL AND LEN(@table_name1) !=0) AND (@column_name1 IS NOT NULL AND LEN(@column_name1) !=0)) 
BEGIN 

    SET @SQLString2 = 'SELECT ' 

    SELECT @SQLString2 += tab.ColName + ' As '+ res.AliasName +',' 
    FROM 
    (
     SELECT QUOTENAME(split.a.value('.', 'VARCHAR(100)')) AS ColName, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNum 
      FROM 
      (
       SELECT Cast ('<M>' + Replace(@column_name1, ',', '</M><M>')+ '</M>' AS XML) AS Data 
      ) AS A 
      CROSS apply data.nodes ('/M') AS Split(a) 
    ) tab 
    INNER JOIN 
    (
     Select AliasSplit.c.value('.', 'varchar(100)') AS AliasName, ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowNum 
     FROM 
     (
      SELECT Cast ('<A>' + Replace(@aliasing_val, ',', '</A><A>')+ '</A>' AS XML) AS AliasData 
     ) AS A 
     CROSS apply AliasData.nodes ('/A') AS AliasSplit(c) 
    ) res 
    ON tab.RowNum = res.RowNum 

    Set @SQLString2 = LEFT(@SQLString2, LEN(@SQLString2) - 1) 

END 


PRINT @SQLString2 

Выход

SELECT [t1col1] As c1,[t1col2] As c2,[t1col3] As c3 
+0

спасибо, это было именно то, что я хотел, хотя результат обоих ответов был точно так, как я ожидал. – cnayak

+0

Рад помочь вам ... ;-) –

2

Это должно сделать работу. Вам нужно отдельно отделять элементы, разделенные запятыми, каждой строкой. Этот скрипт перемещается по элементам и поддерживает указатель на следующий элемент в списке. Затем в каждом цикле он извлекает элемент и добавляет его в SQL:

Declare @table_name1  NVARCHAR(250) = 'table1', 
@column_name1   NVARCHAR(250) = 't1col1,t1col2,t1col3', 
@aliasing_val   NVARCHAR(250) = 'c1,c2,c3', 
@SQLString    nvarchar(max), 
@SQLString2    nvarchar(MAX), 
@count [int], 
@pos int, 
@pos2 [int], 
@delimiter varchar(1); 

SET @delimiter = ','; 
SET @pos = CHARINDEX(@delimiter, @aliasing_val, 1) 
SET @pos2 = CHARINDEX(@delimiter, @column_name1, 1) 
SET @aliasing_val = LTRIM(RTRIM(@aliasing_val)) + @delimiter 
SET @column_name1 = LTRIM(RTRIM(@column_name1)) + @delimiter 
SET @count = 0 

IF ((@table_name1 IS NOT NULL AND LEN(@table_name1) !=0) AND (@column_name1 IS NOT NULL AND LEN(@column_name1) !=0)) 
BEGIN 
    SET @SQLString2 = 'SELECT ' 

    IF REPLACE(@aliasing_val, @delimiter, '') <> '' -- make sure there are actually any delimited items in the list 
    BEGIN 
    WHILE @pos > 0 
    BEGIN 
     IF @count > 0 SET @SQLString2 = @SQLString2 + ',' 
     SET @SQLString2 = @SQLString2 + LTRIM(RTRIM(LEFT(@column_name1, @pos2 - 1))) + ' As ' + LTRIM(RTRIM(LEFT(@aliasing_val, @pos - 1))) 

     SET @aliasing_val = RIGHT(@aliasing_val, LEN(@aliasing_val) - @pos) -- remove the item we just extracted from the list 
     SET @column_name1 = RIGHT(@column_name1, LEN(@column_name1) - @pos2) -- remove the item we just extracted from the list 
     SET @pos = CHARINDEX(@delimiter, @aliasing_val, 1) -- reset the position to point to the next delimiter 
     SET @pos2 = CHARINDEX(@delimiter, @column_name1, 1) -- reset the position to point to the next delimiter 
     SET @count = @count + 1 
    END  
    END 
END 

SELECT @SQLString2 
+0

спасибо, это была новая концепция, которую я узнал. @ADyson – cnayak

Смежные вопросы