在SQL Server中动态别名列名称

时间:2016-08-11 08:59:09

标签: sql sql-server

动态地为每列提供单独的别名值。 @column_name1@aliasing_val中的值可以根据要求进行更改,因此请提供适用于@column_name1@aliasing_val中任意数量值的解决方案。< / p>

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

2 个答案:

答案 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

答案 1 :(得分:1)

你是正确的方法。您唯一需要做的就是为@column_name@aliasing_val制作两个单独的select语句,然后使用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