2017-02-20 3 views
-1

У меня есть таблица сотрудников и программа, которая отображает некоторые критерии запроса, которые пользователь может использовать для SELECT, например, пользователь может искать сотрудника (или набор из них) с помощью сотрудника ID, однако, я разрешаю пользователю выбирать диапазон идентификаторов для выполнения поиска.Между заказанными значениями

В этой реализации БД хранит строковые значения для ID, то они выглядят так:

«000001», «000002» ...., «000200» и так далее, в то время как будучи струнами они также номера. Поэтому, когда я сделать запрос следующим образом:

select * from employees where id_employee BETWEEN '000001' AND '000056' 

Я получаю результаты, которые я бы ожидать, но когда я делаю это:

select * from empleados where id_empleado BETWEEN '000056' AND '000001' 

Я не получаю ничего, казалось бы, как если бы SQLServer лечит valus как целые числа или десятичные значения и, следовательно, не могут получить результаты.

Я могу сделать валидацию в окне критериев, которые я использую, но мне было интересно, если бы был способ сделать это по умолчанию для БД или что-нибудь, что позволило бы мне изменить около 100 этих окон критериев.

Заранее спасибо.

EDIT: Я не спорю о функциональности оператора BETWEEN, а ищет способ использовать его, говоря SQLServer, чтобы сделать это так, как я должен его использовать?

+0

вопрос ... Почему на Земле вы храните FK в качестве значения строки ? Сделайте его правильным значением INT без значения NULL, каким оно должно быть. Если я правильно понял, вы должны использовать эти значения для nvarchar, чтобы заставить его работать. – User987

+1

Возможный дубликат [предложение BETWEEN по сравнению с <= AND > =] (http://stackoverflow.com/questions/4809083/between-clause-versus- и) –

+0

@ User987 Я не администратор базы данных, просто программист, это было уже так, когда я начал работать здесь, и это большая большая программа, так что да, я не думаю, что мы это изменим. Все FK - это в основном строки. –

ответ

0

BETWEEN всегда будет ожидать <smaller value> AND <larger value>. Когда значения меняются на противоположные (<larger value> AND <smaller value>), у вас возникают проблемы.

При использовании параметризованных запросов (настоятельно рекомендуется), то у вас есть окно критерии, которые проходят выбор пользователя в запрос в качестве параметров, что означает, что ваш запрос выглядит следующим образом:

SELECT * from employees WHERE id_employee BETWEEN :Parameter1 AND :Parameter2 

Если это так, то вы можете надеяться, чтобы решить эту проблему, изменив запрос, чтобы запустить CASE сравнение по параметрам, проверьте, какой один больше, а какой меньше, и таким образом решить проблему:

SELECT * 
FROM employees 
WHERE id_employee 
    BETWEEN 
    CASE 
     WHEN :Parameter1 >= :Parameter2 
      THEN :Parameter2 
     ELSE :Parameter1 
    END 
    AND 
    CASE 
     WHEN :Parameter2 <= :Parameter1 
      THEN :Parameter1 
     ELSE :Parameter2 
    END 
; 

Это всего один пример о том, как вы могли это написать, но я думаю, вы получите эту идею.В этом запросе не имеет значения, напишите ли вы :Parameter1 = '00056' и :Parameter2 = '00001' или наоборот; в любом случае возвращаемый результат будет идентичным.

Если каждое окно критериев использует одну и ту же основную логику, то вы, вероятно, не сможете избежать изменения этого в каждом из них.

Это, однако, хороший пример того, как использование централизованных запросов (например, хранимых процедур) может помочь вам сэкономить. Если все ваши окна критериев выполняли хранимую процедуру или аналогичный сохраненный запрос, вы можете просто обновить один центральный запрос, и все окна начнут работать правильно.

Но если каждое окно запускает свой собственный динамический запрос, у вас не будет никакой опции, кроме как перейти в окно за окном и изменить эту функцию.

+0

Это было бы замечательным решением для моей проблемы, если бы программа действительно имела параметризованные запросы, но нет, мы используем запрос dynamyc для каждого окна и что это ERP. Так что да, вы можете представить, сколько из этих запросов есть. Спасибо за ваше время! –

+0

@DavidMerinos Поверьте мне, я чувствую вашу боль. – 3BK

0

Мне немного странно, что вы хотите сохранить свой FK в форме, которую вы здесь указали. Для того, чтобы сделать эту работу, я хотел бы предложить вам использовать целочисленное значение для вашего FK, а затем просто сделать запрос, как это:

select * from empleados where id_empleado BETWEEN 56 AND 1 
0

Даже если вы используете числовые значения результат тот же. SQL переводит between v1 and v2 как >= v1 and <= v2.

declare @emp table (id varchar(10), id2 int); 
insert into @emp values 
('0001',1), 
('0002',2), 
('0010',10), 
('0020',20), 
('0030',30), 
('0040',40); 

select * from @emp where id between '0010' and '0030' 
select * from @emp where id between '0030' and '0010' 

select * from @emp where id2 between 10 and 30 
select * from @emp where id2 between 30 and 10 

Вы можете бросить его в целое:

select * from @emp where cast(id as int) between 10 and 30 

Но результат тот же.

Проверить его здесь: http://rextester.com/IDYU18650

+0

Думаю, он обязательно должен изменить тип FK в своем столе. Этот тип данных для FK совершенно неверен, особенно в том виде, в котором он хранит его, «0000056». – User987

+0

Я знаю, что результат тот же, есть ли способ сказать SQLServer игнорировать порядок аргументов, которые ему были предоставлены, и делать запрос с использованием младшего значения против большего значения? –

+1

@DavidMerinos Нет, нет. Не в SQL Server, а не в Oracle, а не в MySql или PosgreSQL. Это ANSI SQL по умолчанию: BETWEEN возвращает TRUE, если значение test_expression больше или равно значению begin_expression и меньше или равно значению end_expression. – asemprini87

0

Как насчет:

select * from employees where (id_employee BETWEEN '000001' AND '000056') or (id_employee BETWEEN '000056' AND '000001') 

В Powerbuilder языке с два PARM lim1 и LIM2 (определяется как строка):

select * from employees where (id_employee BETWEEN :lim1 AND :lim2) or (id_employee BETWEEN :lim2 AND :lim1) 
Смежные вопросы