Используйте переменную sql для имени столбца - PullRequest
0 голосов
/ 28 ноября 2018

Прежде чем вы кричите на меня в CAPS за то, что я не ищу - у меня есть!Динамический SQL это хорошо, динамический SQL это плохо.Многому научиться ..

Я могу выполнить то, что мне нужно, используя логику в предложении WHERE, но это значительно увеличивает время выполнения.Запрос занимает 8 секунд, если я жестко кодирую критерии, и 1:20, если я использую логику WHERE.

Вот что я хотел бы сделать:

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 голосов
/ 28 ноября 2018

Вот ваш динамический запрос:

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)
0 голосов
/ 28 ноября 2018

Почему бы просто не использовать один запрос?

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 должен использовать индексы для каждого подзапроса - и если у вас есть индексы в полях, запрос должен быть быстрым.

0 голосов
/ 28 ноября 2018

Вы можете остаться со статическим SQL, когда используете выражение CASE в SELECT, а затем фильтруете его.

SELECT *
FROM (
   SELECT *,
          CASE WHEN @EmployeeToggle = '1' THEN Field1 ELSE Field2 END AS Field1_2
   FROM Table1 
) t
WHERE
   Field1_2 = @Employee_ID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...