Проверьте номер проблемы - PullRequest
0 голосов
/ 13 июля 2009

У меня есть столбец с именем check_num (номер банковского чека) в качестве типа VARCHAR2 в таблице payment_line (Oracle).

Требование: «Я должен найти все чеки, числа которых больше 12345.

Подскажите, пожалуйста, как мне этого добиться?

Ответы [ 5 ]

2 голосов
/ 13 июля 2009

Скорее всего, есть более элегантное решение, но это должно сработать:

SELECT * 
FROM payment_line pl 
WHERE LENGTH(TRIM(TRANSLATE(pl.check_num, '0123456789',' '))) IS NULL 
   AND TRIM(TRANSLATE(pl.check_num, '0123456789','0123456789')) > 12345;

редактирование:

Если я понимаю ваш комментарий к Адаму Пейнтеру, для ввода:

0A132 
1A117 
2A123 
12D24 
02134 
11111 
12345 
21334 

и вы использовали 1A117 в качестве сравнения, результирующий набор будет:

2A123 
12D24 
02134 
11111 
12345 
21334

Можете ли вы подтвердить, что 02134 и 11111 должны быть в этом наборе результатов? Кажется, они не соответствуют требованиям >, например 1A117. Однако, если это опечатка, вы можете запустить простое сравнение строк, чтобы получить этот набор:

SELECT * 
FROM payment_line pl
WHERE pl.check_num > '1A117';

редактировать 2

Хорошо, я думаю, что вижу, куда вы идете с этим. Вы ищете, чтобы получить строки в БД, которые были введены после строки ввода. Если вы посмотрите на мой форматированный список выше, вы увидите, что ваш результирующий набор - это все, что находится ниже входной строки. Итак, учитывая это, я представляю на ваше утверждение следующее:

SELECT * 
FROM payment_line  
WHERE rowid > (select rowid from payment_line where check_num ='1A117');
1 голос
/ 13 июля 2009

К сожалению, Oracle не предоставляет удобную функцию, такую ​​как IS_INTEGER(...), в противном случае вы могли бы выполнить запрос, подобный:

-- Fictional, though desirable, query:
SELECT *
FROM  checks
WHERE IS_INTEGER(check_num) AND TO_NUMBER(check_num) > 12345

Однако есть способ эмулировать такую ​​функцию:

-- Real, though less-than-desirable, query:
SELECT *
FROM  checks
WHERE TRIM(TRANSLATE(check_num, '0123456789', '          ')) IS NULL
  AND TO_NUMBER(check_num) > 12345

При вызове TRANSLATE(check_num, '0123456789', ' ') каждая цифра в check_num заменяется пробелом. Например:

 check_num          TRANSLATE(check_num, '0123456789', '          ')
---------------------------------------------------------------------
 '12345'            '     '
 'cat'              'cat'
 '123cat45'         '   cat  '

Следовательно, если check_num содержит только цифр, тогда TRIM(TRANSLATE(check_num, '0123456789', ' ')) будет NULL (то есть пустой строкой).

0 голосов
/ 13 июля 2009

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

Внутренний выбор - получить только числовые контрольные номера. Тогда преобразование и использование предложения where просты. Что-то вроде

выберите * из ( Выбрать * с payment_line где regexp_like (check_num, '^ [0-9] * $') ) где to_number (check_num)> 12345;

Конечно, это работает, только если вы хотите, чтобы все числовые контрольные числа были больше 12345. Если вы хотите, чтобы также были включены "числа", такие как 1A123, это другая история.

0 голосов
/ 13 июля 2009

Сложно использовать to_number () в этом требовании, потому что заставить Oracle применить проверку, что значение безопасно преобразовать в число, прежде чем применить функцию TO_NUMBER, не так просто, и ошибка ORA-01722 может появиться в будущее.

Я думаю, что я бы:

SELECT * 
FROM payment_line pl 
WHERE LENGTH(TRIM(TRANSLATE(pl.check_num, '0123456789',' '))) IS NULL 
   AND LPAD(pl.check_num,10,'0') > TO_CHAR(12345,'fm0000000000');

Вы можете попросить создать индекс на LPAD (pl.check_num, 10, '0'), чтобы помочь с этим.

0 голосов
/ 13 июля 2009

Я надеюсь, что следующее может помочь вам -

select * from checkTable where TO_NUMBER(check_num) > 12345;

ура

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...