使参数的值成为没有动态的列名 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
调用接口来完成列的重命名。
有没有办法在不使用动态 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
调用接口来完成列的重命名。