SQL Server如何将列名链接到外部变量?

SQL Server如何将列名链接到外部变量?,sql,sql-server,database,Sql,Sql Server,Database,我在SQL中编写了一个代码,该代码将一项从列的每条记录中分离出来,而不重复,并且工作正常,请遵循以下代码: SELECT DISTINCT Tab_Dados_Escolha.Nome_Produto FROM Tab_Dados_Escolha 但是,我想用一个外部变量替换这个例程将要执行的列的名称,这样我就可以在其他列中使用相同的代码,而不必重写另一个代码,而且我目前还不能这样做,有人能帮我吗?我正在回答这里提出的问题,但是,正如我提到的,这件衣服的外观和“气味”都很像一只猫。因此,你真的

我在SQL中编写了一个代码,该代码将一项从列的每条记录中分离出来,而不重复,并且工作正常,请遵循以下代码:

SELECT DISTINCT Tab_Dados_Escolha.Nome_Produto FROM Tab_Dados_Escolha

但是,我想用一个外部变量替换这个例程将要执行的列的名称,这样我就可以在其他列中使用相同的代码,而不必重写另一个代码,而且我目前还不能这样做,有人能帮我吗?

我正在回答这里提出的问题,但是,正如我提到的,这件衣服的外观和“气味”都很像一只猫。因此,你真的应该问你真正想要解决的问题,这应该(现在)是一个新问题

至于您所问的问题,正如注释所告诉您的,您不能使用变量/参数来替换列文字。以下面的例子为例:

DECLARE@ColName sysname;
集合@ColName=N'Nome_Produto';
选择DISTINCT@ColName
来自dbo.Tab_Dados_Escolha;
这不会为列
Nome\u Produto
中的每个不同值返回一行。相反,它将返回一个值为
N'Nome\u Produto'
的单行和列。就这样。这是因为变量/参数没有被解释为“返回列的值和
@ColName
的值”,而只是“返回
@ColName
的值”

因此,您需要使用动态SQL并安全地注入值。我还建议验证传递的值,以便在该列不存在时不运行任何(动态)SQL。这意味着您需要执行以下操作:

DECLARE@Colname sysname--你的参数
集合@ColName=N'Nome_Produto'--参数值
声明@SQL nvarchar(最大值);
从dbo.Tab_Dados_Escolha;中选择@SQL=N'SELECT DISTINCT'+QUOTENAME(c.[name])+N'
从sys.s
在s.schema\u id=t.schema\u id上连接sys.t表
连接t.object\u id=c.object\u id上的sys.c列
其中s.[name]=N'dbo'--假定
和t.[name]=N'Tab_Dados_Escolha'
c.[name]=@Colname;
EXEC sys.sp_executesql@SQL;
当然,这些都没有涉及动态SQL的参数化等,但这也是一个非常不同的问题


但是,除非您真正了解如何使用动态SQL,否则不建议使用动态SQL。如果你连这么简单的东西都不懂,就不要用它。相反,请重新思考您的设计,因为它可能有缺陷。

我在回答这里提出的问题,但是,正如我所提到的,它的外观和“气味”都像一辆汽车。因此,你真的应该问你真正想要解决的问题,这应该(现在)是一个新问题

至于您所问的问题,正如注释所告诉您的,您不能使用变量/参数来替换列文字。以下面的例子为例:

DECLARE@ColName sysname;
集合@ColName=N'Nome_Produto';
选择DISTINCT@ColName
来自dbo.Tab_Dados_Escolha;
这不会为列
Nome\u Produto
中的每个不同值返回一行。相反,它将返回一个值为
N'Nome\u Produto'
的单行和列。就这样。这是因为变量/参数没有被解释为“返回列的值和
@ColName
的值”,而只是“返回
@ColName
的值”

因此,您需要使用动态SQL并安全地注入值。我还建议验证传递的值,以便在该列不存在时不运行任何(动态)SQL。这意味着您需要执行以下操作:

DECLARE@Colname sysname--你的参数
集合@ColName=N'Nome_Produto'--参数值
声明@SQL nvarchar(最大值);
从dbo.Tab_Dados_Escolha;中选择@SQL=N'SELECT DISTINCT'+QUOTENAME(c.[name])+N'
从sys.s
在s.schema\u id=t.schema\u id上连接sys.t表
连接t.object\u id=c.object\u id上的sys.c列
其中s.[name]=N'dbo'--假定
和t.[name]=N'Tab_Dados_Escolha'
c.[name]=@Colname;
EXEC sys.sp_executesql@SQL;
当然,这些都没有涉及动态SQL的参数化等,但这也是一个非常不同的问题


但是,除非您真正了解如何使用动态SQL,否则不建议使用动态SQL。如果你连这么简单的东西都不懂,就不要用它。相反,请重新考虑您的设计,因为它可能有缺陷。

您必须使用动态SQL——也就是说,将查询构造为字符串,然后执行它。不建议这样做,因为这样会打开SQL注入攻击和意外语法错误的代码。不能使用变量替换文字,必须使用动态SQL并将值安全地注入语句。此外,对于类似的情况,您最好使用
DISTINCT
而不是
GROUP BY
<代码>分组依据用于执行某种形式的聚合。您不能。表和列相当于强类型函数语言中的类型和字段。当查询引擎解析查询时,必须知道这些模式。SQL查询是编译到执行计划中的语言,就像C或F代码被编译到可执行文件中一样。查询参数与程序的参数相同。它们不会影响已编译的程序,它们是itI使用的数据,我怀疑这确实是一个错误。您真正想要解决的问题是什么?实际上,该查询本质上是一个
不同的
。那么为什么要使用
分组方式呢?你想避免什么重复?您是否正在尝试像Pandas或.NET DataFrame那样分析表的内容?这些库不单独计算度量值,因为这需要多次读取数据。对每一列执行一个DISTINCT意味着扫描整个t