Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:选择预定义的列列表_Sql_Sql Server - Fatal编程技术网

SQL:选择预定义的列列表

SQL:选择预定义的列列表,sql,sql-server,Sql,Sql Server,我想做如下声明: SELECT @column_list FROM table_name 如何实现这一点?您需要使用动态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\u l

我想做如下声明:

SELECT @column_list FROM table_name

如何实现这一点?

您需要使用动态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\u list
可能来自另一个查询的结果,例如对信息架构表的查询,以查找特定的列组

如果还需要使用信息架构表中的列动态生成查询,则有一个选项:

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注入的恐惧,我不认为上面的查询是一个很大的风险,因为列名来自SQLServer。< /P> < P>该选项通过确保列存在于表中,从而消除了注入的危险,并引用了列的名称:

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+上,您可以使用/或am XML拆分器(如果您要传递的列表长度超过4000个字符)

我不确定您在寻找什么,但下面的查询可能会对您有所帮助。你可以试试这个

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'

注射方面有点吓人(这一个)@Larnu我假设有人(例如DBA)将从SSMS运行此操作,并且列列表不会来自外部。但是,是的,这完全可以被注入。事实上,我正在学习ADO.NET,我试图在我的代码中避免SQL注入,还有其他方法吗?这本身就是一个可怕的假设。。你信任DBA吗?;)如果列表来自服务器端而不是用户,那么第二个选项当然是更好的选项。但是,如果表中有特殊字符(即空白),则在运行时可能会失败。如果您可以提供所需的输出,则这将有助于社区更准确地帮助您。在我的回答中,关于SQL注入的一条注释就足够了。我不认为这个问题是一个很大的注入风险,因为列名将来自SQL Server内部,而不是来自外部,例如UI。@ TimBiegeleisen不确定你的观点是什么。这里的答案是这样构建的,因为注入是真实的。我在回答中没有提到这是构建它的方式,这并不能解释这一点。