使参数的值成为没有动态的列名 SQL

Make value of a parameter the column name without dynamic SQL

有没有办法在不使用动态 SQL 的情况下将列命名为参数中的值?

我需要以某种方式输出 @input 参数中的值作为 SQL 语句中列的名称。我需要避免使用动态 SQL.

DECLARE @input VARCHAR(10)=' Person '; 

SELECT count(*) AS  @input + ' Open Data'    
FROM #Accounts a
JOIN dbo.FileFeed t On t.ID = a.AccountID     
GROUP BY a.accountid

您需要使用动态 SQL:

DECLARE @input VARCHAR(10) = ' Person '; 

DECLARE @sql NVARCHAR(MAX) = '
SELECT count(*) AS  [@Input Open Data]    
FROM #Accounts a JOIN
     dbo.FileFeed t
     On t.ID = a.AccountID     
GROUP BY a.accountid';

SET @sql = REPLACE(@sql, '@Input', @Input);

exec sp_executesql @sql;

不过,我真的不认为这是个好主意。如果您需要重命名列,请在应用程序代码中执行。

答案是"No"。根据定义,动态 SQL 意味着代码可以自行改变。 Dynamic SQL 的唯一替代方法是 Hard-Coded SQL,也就是您专门自己编写每一部分。

您询问是否可以根据变量更改字段名称,这只能通过动态 SQL 来完成。

一个丑陋的方式,没有Dynamic-SQL使用临时table并重命名列:

DECLARE @input VARCHAR(10) = ' Person '; 
DECLARE @new_name VARCHAR(100) = @input + ' Open Data';

SELECT [rename_me] = COUNT(*)
INTO #temp    
FROM #Accounts a
JOIN dbo.FileFeed t On t.ID = a.AccountID     
GROUP BY a.accountid;

EXEC tempdb..sp_rename '#temp.rename_me', @new_name, 'COLUMN';

SELECT * 
FROM #temp;

没有。数据库使用类似于编译的过程将您的查询转换为执行计划。此过程的一部分涉及确定用户 运行 查询是否有权访问查询使用的表和列。如果直到执行时才确定这些表和列,则编译步骤无法完成。看起来很奇怪,但是同样的事情也适用于结果集。

动态 SQL(它创建一个新查询,带有一个新的编译步骤,其中表名和列名是预先知道的)将是实现此目的的唯一方法。

除非您重命名应用程序中的列,否则我会这样做。

DECLARE @input VARCHAR(10)=' Person '; 
Declare @sql varchar(max);
set @sql'SELECT count(*) as ['+ @input +' Open Data]
FROM #Accounts a
JOIN dbo.FileFeed t On t.ID = a.AccountID     
GROUP BY a.accountid';

EXEC(@sql);

IF @input 变量/参数中的值是有限的(即不是开放式用户输入或那种性质),那么您可以在没有 DynamicSQL 的情况下执行此操作。您只需要在这个存储过程中有多个查询副本,除了列的别名外,每个副本都完全相同,然后根据变量的值选择您想要的副本。例如:

DECLARE @input VARCHAR(10)=' Person '; 

IF (@input = 'Person')
BEGIN
  SELECT COUNT(*) AS [Person Open Data]
  FROM #Accounts a
  JOIN dbo.FileFeed t
    ON t.ID = a.AccountID     
  GROUP BY a.accountid;
END;

IF (@input = 'Account')
BEGIN
  SELECT COUNT(*) AS [Account Open Data]
  FROM #Accounts a
  JOIN dbo.FileFeed t
    ON t.ID = a.AccountID     
  GROUP BY a.accountid;
END;

...

如果您有更高版本的 SQL 服务器,那么您可能会查看此选项:

EXEC <stored_procedure> WITH RESULT SETS (...)

我想您已经在使用存储过程了。这样,您至少能够在第二个过程中保持主要逻辑完全静态,并且只需通过动态 exec 调用接口来完成列的重命名。