我想做如下声明:
SELECT @column_list FROM table_name
我该如何实现?
答案 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'