以列名作为输入参数的存储过程中的动态 sql
Posted
技术标签:
【中文标题】以列名作为输入参数的存储过程中的动态 sql【英文标题】:dynamic sql in stored procedure with column name as input parameter 【发布时间】:2014-03-11 17:28:07 【问题描述】:我有这个存储过程,它接受一个 comlumn 名称作为 inptu 参数。 SELECT语句会根据输入参数选择一列
create procedure getColumn (@whichColumn varchar)
as
begin
declare @sql nvarchar(max)
set @sql = 'SELECT [' + @whichColumn + ']'
+ ' FROM myTable'
+ ' where ['+ @whichColumn + '] is not null'
+ ' and [' + @whichColumn + '] != '''' ' ;
exec sp_executesql @sql
end
当我执行这个存储过程时,
exec getColumn 'Apple';
错误提示“无效的列名'A'”。 我不明白为什么它只获取输入的第一个字符
【问题讨论】:
【参考方案1】:查看您的参数声明:
@whichColumn varchar
From MSDN:
当 n 未在数据定义或变量声明中指定时 语句,默认长度为1。
所以这是一个单字母varchar
。尝试指定大小:
@whichColumn varchar(50)
或者更好的是,使用系统定义的类型作为对象名称:
@whichColumn sysname
【讨论】:
^^^^这是你的答案。始终声明列的长度。 如果没有提到长度,我以为是 30 :S @M.Ali:如果你省略了cast
和convert
中的长度,那是真的。但在变量声明中,默认长度为 1。你可以vote here来解决这个疯狂问题。
opss 搞混了。 :) 我试过投票,但它不会让我稍后再试。
/sigh 这不是公认的答案这一事实令人不安。【参考方案2】:
create procedure getColumn (@whichColumn nvarchar(128)) --<-- Maximum column name lenght
as
begin
declare @sql nvarchar(max);
set @sql = N'SELECT ' + QUOTENAME(@whichColumn)+ N' FROM myTable'
+ N' where '+ QUOTENAME(@whichColumn) + N' is not null'
+ N' and ' + QUOTENAME(@whichColumn) + N' != '''' ' ;
exec sp_executesql @sql
end
附带说明 在连接字符串中使用方括号与使用 QUOTENAME 函数不同。
【讨论】:
您是否愿意对投反对票的人发表评论? +1 失去平衡。也不知道你为什么拿到 DV。 干杯 Zane 有一些 numties 反对投票来取乐。我希望有一个系统,每次有人不公平地投票时,他们的声誉都会-100:S M.阿里在阅读您建议的答案之前,我不知道 TSQL 关键字 QUOTENAME。它解决了我在编写动态 SQL 以在 UPDATE 存储过程中设置列名的问题。一个好处是编写和理解恕我直言更干净。【参考方案3】:改变这一行
create procedure getClumn (@whichColumn varchar)
到
create procedure getClumn (@whichColumn varchar(max))
因为如果你当时没有分配 varchar 的大小,它只考虑一个字符,所以它只得到一个字符 A 并产生错误。
【讨论】:
哇,我们不要得意忘形,一路走到VARCHAR(MAX)
,我的假设是他可能需要不到 8,000 个字符来完成这项工作。
@Zane 我的假设是他永远不需要超过 128 :)以上是关于以列名作为输入参数的存储过程中的动态 sql的主要内容,如果未能解决你的问题,请参考以下文章