首页 > 解决方案 > 如何传递包含在 SQL Server 中声明的变量中的列

问题描述

我有一个Depots看起来像这样的表:

仓库编号 仓库名称 仓库位置 别名
1 欧兰 实用性 欧拉
2 英格里 实用性 英格拉斯
3 土耳其人 实用性 图尔库
4 夯实 乌西马 坦佩雷
5 科科斯 乌西马 科库拉
6 考斯 奥隆巴 考卡纳

我在声明的变量中存储了一个逗号分隔的列列表@ValList

DECLARE @ValList varchar(8000);
SET @ValList = NULL

SELECT @ValList = COALESCE(@ValList + ', ','') + ColumnName 
FROM #list

@ValList返回DepotID, DepotName, DepLocation

我想传入@ValList如下的选择语句

SELECT @ValList FROM Depots

所以我得到

仓库编号 仓库名称 仓库位置
1 欧兰 实用性
2 英格里 实用性
3 土耳其人 实用性
4 夯实 乌西马
5 科科斯 乌西马
6 考斯 奥隆巴

但我不断得到类似的东西

(无列名)
仓库 ID、仓库名称、仓库位置
仓库 ID、仓库名称、仓库位置
仓库 ID、仓库名称、仓库位置
仓库 ID、仓库名称、仓库位置
仓库 ID、仓库名称、仓库位置
仓库 ID、仓库名称、仓库位置

我究竟做错了什么?

标签: sqlsql-servervariablesdynamic-sql

解决方案


不确定您可以或应该信任多少列列表的来源,但最安全的方法如下,您可以在其中检查每个列是否存在sys.columns

CREATE TABLE #list(ColumnName sysname);

INSERT #list(ColumnName) 
VALUES(N'DepotID'),(N'DepotName'),(N'DepLocation');

DECLARE @sql nvarchar(max), @cols nvarchar(max) = N'';

SELECT @cols += N',' + QUOTENAME(c.name) 
  FROM #List AS l
  INNER JOIN sys.columns AS c
  ON l.ColumnName = c.name
  WHERE c.[object_id] = OBJECT_ID(N'dbo.Depots');
  
SET @sql = N'SELECT ' + STUFF(@cols, 1, 1, N'') 
  + N' FROM dbo.Depots';
  
EXEC sys.sp_executesql @sql;

保护自己免受 SQL 注入:第 1 部分| 第2部分


推荐阅读