SQL:根据变量选择动态列名

SQL:根据变量选择动态列名,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我有一个Microsoft SQL存储过程,我想通过传入该过程的变量设置其列名: CREATE PROCEDURE [My_Procedure] @myDynamicColumn varchar(50) AS BEGIN SELECT 'value' AS @myDynamicColumn END 这不起作用(“语法不正确”)。如果我将列名换行为[]: SELECT 'value' AS [@myDynamicColumn] 列名输出为“@myDynamicColumn”,而不是

我有一个Microsoft SQL存储过程,我想通过传入该过程的变量设置其列名:

CREATE PROCEDURE [My_Procedure]
   @myDynamicColumn varchar(50)
AS BEGIN
   SELECT 'value' AS @myDynamicColumn
END
这不起作用(“语法不正确”)。如果我将列名换行为[]:

SELECT 'value' AS [@myDynamicColumn]

列名输出为“@myDynamicColumn”,而不是实际值。有没有办法做到这一点?我看过动态SQL文章,但没有什么是我想要的。

您可以将查询构建为字符串并使用exec

EXEC ('SELECT ''value'' AS ' + @myDynamicColumn)
CREATE PROCEDURE [My_Procedure]
   @myDynamicColumn varchar(50)
AS BEGIN
   EXEC('SELECT ''value'' AS ' + @myDynamicColumn)
END

这两个投票结果都非常危险,都容易受到注射攻击,不应该使用

注入动态对象名称时,必须确保正确引用对象名称。SQL Server有一个内置函数,
QUOTENAME
。因此,您实际应该做的是:

CREATE PROCEDURE[My_PROCEDURE]@myDynamicColumn sysname
作为开始
声明@SQL nvarchar(MAX)=N'选择“值”为'+QUOTENAME(@myDynamicColumn)+N';';
EXEC sys.sp_executesql@SQL;
结束

您会注意到,我还将参数的数据类型更改为
sysname
,它是
nvarchar(128)notnull
的同义词,SQL Server内部使用该数据类型作为对象名称。

为什么?SQL不应该是这样的used@gbn:马上@dotNewkow:我相信这只是一个人为的例子来说明你的问题,但gbn是正确的:这很复杂,因为它是错误的。如果需要为存储过程中的返回设置别名,那么只需在调用代码中设置别名,显然您已经知道@myDynamicColumn的值。如果您发布更多关于您的问题的详细信息,也许我们可以提供比动态sql更多的信息。好问题。是的,我理解动态SQL的危险@Nathan Skerl,你是对的,通常你会想通过呼叫代码来设置。但是,出于报告目的,我在Excel中将此查询作为数据连接运行。客户机需要4个数据相对相同但列名不同的报表,因此我制作了一个可重用的存储过程&遵循DRY原则。如果这是一个视图,我可以这样做:“从[My view]中选择[column]作为[My Dynamic column name]”,但由于它是一个存储过程,我只能执行“EXEC My_Procedure‘My column name’”。DRY将在客户端中为其别名,并保持SQL协定相同。这不是SQL问题。DRY也意味着使用相同的名称。一个属性有4个名称是令人困惑的…将过程更改为接受@ReportId,然后在过程中模拟您在视图中的操作如何。。。例如,如果@ReportId=1,则选择“值”作为[MyDynamicColumn],否则如果@ReportId=2。。。至少你不必承担动态sql的包袱。对于少量的报告/专栏标题,我会选择这条路线。谢谢,你在另一个人回答45秒后回答了,所以请进行投票@多特内特科:事实上,我比“另一个男人”领先9秒,15:49:30对15:49:39。一直是伴娘,从来都不是新娘。你好,未来10年!你是对的,这是一个创造性的解决方案,解决了我很久以前遇到的一个问题。它位于不同的注释中,但是:出于报告目的,查询是作为Excel中的数据连接运行的。客户需要4个数据相对相同但列名不同的报表,因此我制作了一个可重用的存储过程&遵循DRY原则。仅在内部运行,存储过程在传递给客户端之前从Excel中剥离。干杯