SQL:选择预定义的列列表

时间:2018-10-26 09:05:18

标签: sql sql-server

我想做如下声明:

SELECT @column_list FROM table_name

我该如何实现?

3 个答案:

答案 0 :(得分:2)

您需要为此使用动态SQL:

DECLARE @sql varchar(500)
DECLARE @column_list varchar(100)
SET @column_list = 'col1, col2, col3'
SET @sql = 'SELECT ' + @column_list + ' FROM table_name';
EXEC (@sql)

请注意,@column_list可能来自另一个查询的结果,例如在Information Schema表上查询以找到一组特定的列。

如果您还需要使用信息架构表中的列动态构建查询,那么这里是一个选择:

DECLARE @sql varchar(1000)
DECLARE @column_list varchar(500)
SET @column_list = 'col1, col2, col3'

SELECT @column_list = 
    STUFF((
        SELECT ',' + COLUMN_NAME
        FROM information_schema.columns
        WHERE table_name = 'yourTable'
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')

SET @sql = 'SELECT ' + @column_list + ' FROM yourTable';
EXEC (@sql)

要解决对SQL注入的担心,我认为上面的查询不会带来很大的风险,因为列名来自SQL Server。

答案 1 :(得分:1)

此选项通过确保表中存在该列来消除注入的危险,并引用该列的名称:

USE Sandbox;
GO

CREATE TABLE Table_name (ID int,
                         SomeString varchar(500));

DECLARE @column_list nvarchar(MAX);
DECLARE @SQL nvarchar(MAX);

SET @column_list = 'ID,Somestring'; --Don't use spaces in the list

SET @SQL = N'SELECT ' +
           STUFF((SELECT N',' + NCHAR(10) + N'       ' + QUOTENAME(SS.value)
                  FROM STRING_SPLIT(@column_list,',') SS
                  WHERE EXISTS (SELECT 1
                                FROM sys.tables t
                                     JOIN sys.columns c ON t.object_id = c.object_id
                                     JOIN sys.schemas s ON t.schema_id = s.schema_id
                                WHERE t.name = N'Table_name' --Change this the applicable table
                                  AND c.name = SS.value
                                  AND s.name = 'dbo') --change this to the applicable schema
                  FOR XML PATH(N'')),1,9,N'') + NCHAR(10) +
           N'FROM Table_name;';
PRINT @SQL;

EXEC sp_executesql @SQL;
GO
DROP TABLE Table_name;

如果您未使用SQL Server 2016+,则可以使用DelimitedSplit8k / DelimitedSplit8K_Lead或XML拆分器(如果要传递的列表长度超过4000个字符)

答案 2 :(得分:0)

我不确定您在寻找什么,但是下面的查询可能会为您提供帮助。你可以试试看。

select t.Name AS TableName, c.Name AS ColumnName from sys.tables t
INNER JOIN sys.columns c
ON c.object_id = t.object_id
WHERE t.name  = 'YOUR_TABLE_NAME'