将列名称作为参数传递时,查询显示的输出不正确

时间:2016-10-19 15:57:48

标签: sql sql-server-2008

这是我的代码。   HEADER_ID是主键。   EFFECTIVE_DATE是列名,包含唯一值。

declare @ColumnName varchar(20)
    set @ColumnName='EFFECTIVE_DATE'
     select * into #temphdrid 
     from  EMP_HEADER a 
    where 
    EMPLOYEE_ID in ('1111','2222') and  
    HEADER_ID=(select  max(HEADER_ID) from EMP_HEADER b where 
    a.HEADER_ID=b.HEADER_ID and    @ColumnName=(select MAX(@ColumnName) from EMP_HEADER c
    where b.EMPLOYEE_ID=c.EMPLOYEE_ID and YEAR(FIN_START_DATE)=2016)
    and YEAR(FIN_START_DATE)=2016)
    and YEAR(FIN_START_DATE)=2016

当我传递@ColumnName而不是EFFECTIVE_DATE时,它显示10行,但是每个员工应显示单行,在这种情况下为2行。

如果我直接通过EFFECTIVE_DATE,那么它正常工作。

请帮忙,因为我无法理解究竟是什么问题。

2 个答案:

答案 0 :(得分:4)

长话短说:你想要做的事是不可能的;你需要修复你的方法。

声明变量@ColumnName时,它不会被解释为列名;它始终被解释为数据值 - 在您的情况下,它与'EFFECTIVE_DATE'字符串文字相同。实际上,您的查询就像编写如下:

select * into #temphdrid 
from  EMP_HEADER a 
where 
EMPLOYEE_ID in ('1111','2222') and  
HEADER_ID=(select  max(HEADER_ID) from EMP_HEADER b where 
a.HEADER_ID=b.HEADER_ID
and 'EFFECTIVE_DATE'=(select MAX('EFFECTIVE_DATE') from EMP_HEADER c
where b.EMPLOYEE_ID=c.EMPLOYEE_ID and YEAR(FIN_START_DATE)=2016)
and YEAR(FIN_START_DATE)=2016)
and YEAR(FIN_START_DATE)=2016

这在语法上是正确的,但没有意义,因为MAX('EFFECTIVE_DATE')总是等于'EFFECTIVE_DATE'

另一种方法是提供一些指示,说明需要选择哪个列名,并使用case表达式进行比较:

declare @ColIdx tinyint
set @ColIdx=1
...
where 
a.HEADER_ID=b.HEADER_ID
and (case @ColInd when 1 then EFFECTIVE_DATE when 2 then END_DATE else null end)=(select MAX(case @ColInd when 1 then EFFECTIVE_DATE when 2 then END_DATE else null end) from

答案 1 :(得分:1)

如果要在该变量

中传递不同的列名,则动态查询是唯一的方法
declare @ColumnName varchar(20)
    set @ColumnName='EFFECTIVE_DATE'

Declare @sql varchar(max) = ''
set @ColumnName=QUOTENAME(@ColumnName)

  set @sql =  '  select * into #temphdrid 
     from  EMP_HEADER a 
    where 
    EMPLOYEE_ID in ('1111','2222') and  
    HEADER_ID=(select  max(HEADER_ID) from EMP_HEADER b where 
    a.HEADER_ID=b.HEADER_ID and    '+ @ColumnName +' =(select MAX('+ @ColumnName +') from EMP_HEADER c
    where b.EMPLOYEE_ID=c.EMPLOYEE_ID and YEAR(FIN_START_DATE)=2016)
    and YEAR(FIN_START_DATE)=2016)
    and YEAR(FIN_START_DATE)=2016'

Exec (@sql)

注意:无法在外部访问动态查询中创建的临时表。如果要访问外部,请先在之前创建表,然后在动态查询中使用INSERT INTO #temphdrid SELECT..