如何在动态sql查询中引用字段?
我在sql Server中有一个动态sql查询。所以我构建它,将它设置为一个变量,然后尝试根据日期设置where子句的格式。但是,当我尝试这样做时,我得到的“多部分标识符的字段名”无法绑定。我认为这是因为实际的表是从克劳斯动态生成的,所以在编译之前无法看到它们。有办法吗 这里我想说的是,给我指定年份+月份之间DOB的所有人员,例如,201001和201012将是2010年的整个年份。下面是代码的一部分如何在动态sql查询中引用字段?,sql,sql-server,sql-server-2008,stored-procedures,Sql,Sql Server,Sql Server 2008,Stored Procedures,我在sql Server中有一个动态sql查询。所以我构建它,将它设置为一个变量,然后尝试根据日期设置where子句的格式。但是,当我尝试这样做时,我得到的“多部分标识符的字段名”无法绑定。我认为这是因为实际的表是从克劳斯动态生成的,所以在编译之前无法看到它们。有办法吗 这里我想说的是,给我指定年份+月份之间DOB的所有人员,例如,201001和201012将是2010年的整个年份。下面是代码的一部分 ALTER PROCEDURE get_persons_by_search_crite
ALTER PROCEDURE get_persons_by_search_criteria
@month_from as nvarchar(2) = null,
@year_from as nvarchar(4) = null,
@month_to as nvarchar(2) = null,
@year_to as nvarchar(4) = null
AS
declare @from_date varchar(10)
declare @to_date varchar(10)
declare @sqlstr varchar(5000)
set @sqlstr = ' SELECT
Person.PersonID,
Person.FirstName,
Person.LastName,
FROM Person '
--Attemtping to create a value like 201108 (year + month)
set @from_date = Convert(VarChar(10), @year_from) + Replace(Str(@month_from, 2), ' ', '0')
set @to_date = Convert(VarChar(10), @year_to) + Replace(Str(@month_to, 2), ' ', '0')
set @sqlstr = @sqlstr + ' WHERE '
set @sqlstr = @sqlstr + Convert(VarChar(10), Person.DOBYear) + Replace(Str(Person.DOBMonth, 2), ' ', '0')
set @sqlstr = @sqlstr + ' BETWEEN ' + @from_date + ' and ' + @to_date
exec(@sqlstr)
此行给出了错误,因为在构建动态字符串时PERSON表未打开
set @sqlstr = @sqlstr + Convert(VarChar(10), Person.DOBYear) + Replace(Str(Person.DOBMonth, 2), ' ', '0')
试试这个
set @sqlstr = @sqlstr + ' Convert(VarChar(10), Person.DOBYear) + Replace(Str(Person.DOBMonth, 2), '' '', ''0'') '
我知道你已经解决了你的问题并接受了答案,但我想我还应该指出一些其他潜在的改进(对你和这个问题的未来读者都是如此) 这不是更容易看上眼睛,更容易遵循,更容易维护吗 总结:
- 创建、更改或引用对象时
- 当您不需要支持Unicode数据时,不要使用Unicode(
/NCHAR
)(例如,数字永远不需要包含UMLAUT)。在这种情况下可能没有那么重要,但在其他情况下可能至关重要NVARCHAR
- 在
/开始
中包装您的过程主体-这将防止您无意中从查询窗口提取其他不需要的代码。并始终在程序开始时使用结束
。我在“我的”中解决了这些和其他问题SET NOCOUNT ON
- 为避免行为发生变化,应始终包含一个
子句。如果今天它按名字下单,明天开始按姓氏下单,就会有人抱怨。见第二节orderby
- 尽可能学习在没有动态SQL的情况下编写SQL。如果要继续使用动态SQL,至少请尝试使用而不是。我在最近的另一个问题中解释了原因:
EXEC get_persons_by_search_criteria
@month_from = '97',
@year_from = 'Audi',
@month_to = 'TT',
@year_to = 'Oy!!';
他们可以这样做,因为你不执行任何验证。对于日期变量,至少返回的错误消息是有意义的。现在,对于我们的任何一个版本,它们只会得到一个空的结果集。这看起来不需要是动态SQL。为什么不能使用上一个问题中的?提问时请指出SQL Server的版本@Martin的内存显然比我的好,但我们并不都知道上次有人问你“SQL Server的版本是什么?”
EXEC get_persons_by_search_criteria
@month_from = '97',
@year_from = 'Audi',
@month_to = 'TT',
@year_to = 'Oy!!';