将参数的值设为不带动态SQL的列名
有没有一种方法可以在不使用动态SQL的情况下,将参数中的值命名为列 我需要以某种方式将@input参数中的值作为SQL语句中列的名称输出。我需要避免使用动态SQL将参数的值设为不带动态SQL的列名,sql,sql-server,parameters,ssms,Sql,Sql Server,Parameters,Ssms,有没有一种方法可以在不使用动态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.accoun
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;
然而,我真的认为这不是一个好主意。如果需要重命名列,请在应用程序代码中进行重命名。答案是否定的。根据定义,动态SQL意味着代码可以自行更改。动态SQL的唯一替代方法是硬编码SQL,当您自己专门编写它的每一部分时 您询问是否可以基于变量更改字段名,这只能通过动态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
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);
如果@input变量/参数中的值受到限制,即不是开放式用户输入或类似性质的内容,那么您可以在不使用DynamicSQL的情况下执行此操作。您只需要在此存储过程中拥有查询的多个副本,每个副本除了列的别名外都完全相同,然后根据变量的值选择所需的副本。例如:
声明@input VARCHAR10='Person';
如果@input='Person'
开始
选择计数*作为[个人开放数据]
从帐户a
JOIN dbo.FileFeed t
在t.ID=a.AccountID上
按a.accountid分组;
终止
如果@input='Account'
开始
选择COUNT*作为[开户数据]
从帐户a
JOIN dbo.FileFeed t
在t.ID=a.AccountID上
按a.accountid分组;
终止
...
如果您有更高版本的SQL Server,则可以查看以下选项:
EXEC <stored_procedure> WITH RESULT SETS (...)
我想您已经在使用存储过程了。通过这种方式,您至少可以在第二个过程中保持主逻辑完全静态,只需使用dynamic exec调用与过程接口即可完成列的重命名。为什么不直接在客户端处理它呢,为查询分配一些内部名称并在您使用的任何UI中很好地显示它?哦,我完全同意客户端应该处理命名约定,但我继承了旧代码。这意味着很多东西都在使用这段代码,而不仅仅是我的应用程序,而且总是很难找到所有东西。变量中的值是开放式输入还是有限的值?我完全同意应用程序应该处理命名约定,但当你继承某个东西时,它会发出臭味写在很久以前,并试图追踪所有调用它的东西。