将变量sql用于列名

时间:2018-11-28 14:39:03

标签: sql sql-server tsql dynamic-sql

在您以CAPS对我大喊不搜索之前-我有!动态SQL很好,动态SQL不好。学到很多东西。

我可以通过在WHERE子句中使用逻辑来完成我要执行的操作,但是这会增加大量的运行时间。如果我对条件进行硬编码,则查询将花费8秒,如果使用WHERE逻辑,则查询将花费1:20。

这就是我想要做的:

Declare @EmployeeToggle varchar(30)
Declare @Employee_ID varchar(30)
Declare @EmployeeField varchar(100)

set @EmployeeToggle = '1'
set @Employee_ID = '1166'
set @EmployeeField = case when @EmployeeToggle = '1' then 'Field1' else 
'Field2' end;

select * from Table1 where @EmployeeField = @Employee_ID

我认为没有动态sql是不可能的。我仍然不知道我是否应该使用它。我认为这将使查询缩短到8秒,因为它会立即知道在where子句中使用哪个字段。

或者,只有几种方法可以做到:

where (( not @EmployeeToggle = '1') or Field1 = @Employee_ID) and 
(@EmployeeToggle = '1' or Field2 = @Employee_ID)


where (1=(case when @EmployeeToggle = '1' then 1 else 0 end ) or Field1 = 
@Employee_ID)
and (1=(case when @EmployeeToggle = '2' then 1 else 0 end) or Field2 = 
@Employee_ID)

这些工作很棒(诚然,我复制并粘贴了这些示例),但是却要花费运行时间。

我的最终想法以及其他在我的组织中所做的工作方式,是创建两个脚本,除了where子句中使用的字段外,它们完全相同。因此,如果@EmployeeToggle ='1',它将运行第一个脚本,如果它是'2',它将运行第二个脚本。我还没有尝试过,但是我认为运行时将接近8秒,但会花费一些难看的代码。

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

为什么不只使用一个查询?

select t.*
from table1
where @EmployeeToggle = '1' and field_1 = @Employee_ID
union all
select t.*
from table1
where @EmployeeToggle <> '1' and field_2 = @Employee_ID;

通过使用union all,SQL Server应该为每个子查询使用索引-如果您在字段上有索引,则查询应该很快。

答案 1 :(得分:1)

在SELECT中使用CASE表达式然后对其进行过滤时,您可以保留静态SQL。

SELECT *
FROM (
   SELECT *,
          CASE WHEN @EmployeeToggle = '1' THEN Field1 ELSE Field2 END AS Field1_2
   FROM Table1 
) t
WHERE
   Field1_2 = @Employee_ID

答案 2 :(得分:0)

这是您的动态查询:

Declare @EmployeeToggle varchar(30)
Declare @Employee_ID varchar(30)
Declare @EmployeeField varchar(100)

set @EmployeeToggle = '1'
set @Employee_ID = '1166'
set @EmployeeField = case when @EmployeeToggle = '1' then 'Field1' else 
'Field2' end;

DECLARE @SQLString  VARCHAR(MAX)

SET @SQLString='select * 
                from Table1 
                where '+@EmployeeField+' = '+@Employee_ID+''

PRINT(@SQLString) --If you want to check actual query
EXEC(@SQLString)