Могу ли я использовать подстановочные знаки в функции ПОЛОЖЕНИЯ Firebird - PullRequest
1 голос
/ 30 марта 2020

Я использую Firebird 2.1.

У меня есть номер заказа на работу, который может иметь 1 или 2 буквенных символа, затем 4 или 5 номеров, а затем, возможно, префикс с 1 буквенным символом и 2 номерами.

Я хочу извлечь число 4-5 di git в середине.

Я попробовал следующее, чтобы найти номер символа, но он вернул 0:

POSITION('%[0-9]%',JOBHEADER.ORDERNUMBER,1) AS "FIRST NUMBER"

Я не уверен, что смогу использовать подстановочные знаки с POSITION функция. Я думаю, я мог бы попытаться проверить номер 2-го или 3-го символа, но мне действительно нужна функция подстановки, чтобы найти следующую альфу после того, как я найду положение первого числа. Или, может быть, есть другое решение, чтобы извлечь номер.

Я нашел что-то похожее:

CASE WHEN SUBSTRING(ordernumber FROM 2 FOR 5) SIMILAR TO '[0-9]+'
     THEN SUBSTRING(ordernumber FROM 2 FOR 5)
     ELSE SUBSTRING(ordernumber FROM 3 FOR 5)
END as PROJECTNUMBER

Но с числом, начинающимся с первых 5 символов, оператор if / case начинает становиться довольно большим.

1 Ответ

0 голосов
/ 30 марта 2020

Нет, вы не можете сделать это с POSITION. Позиция ищет точную подстроку в данной строке. Однако в Firebird 3 вы можете использовать SUBSTRING с регулярными выражениями для извлечения значения, например:

substring(ordernumber similar '%#"[[:DIGIT:]]+#"%' escape '#')

Регулярное выражение должно охватывать всю строку, тогда как #" включает термин для извлечения (# является явно определенным escape-символом). Возможно, вам придется использовать более сложные шаблоны, такие как [^[:DIGIT:]]*#"[[:DIGIT:]]+#"([^[:DIGIT:]]%)?, чтобы избежать краевых падежей в жадности.

Если вы знаете, что шаблон всегда состоит из 1 или 2 букв, 4 или 5 цифр, которые вы хотите извлечь, возможно, после 1 альфа и 2 цифры, вы также можете использовать [[:ALPHA:]]{1,2}#"[[:DIGIT:]]{4,5}#"([[:ALPHA:]][[:DIGIT:]]{1,2})?. Если шаблон не соответствует, возвращается null.

См. Также:

Имейте в виду, что стандартный синтаксис регулярных выражений SQL, поддерживаемый Firebird, немного странный и менее мощный, чем обычные выражения, распространенные в других языках.

Использование PSQL

Чтобы решить эту проблему с помощью PSQL, в Firebird 2.1 вы можете использовать что-то вроде:

create or alter procedure extract_number(input_value varchar(50)) 
    returns (output_value bigint)
as
declare char_position integer = 0;
declare number_string varchar(20) = '';
declare current_char char(1);
begin
  while (char_position < char_length(input_value)) do
  begin
    char_position = char_position + 1;
    current_char = substring(input_value from char_position for 1);
    if ('0' <= current_char and current_char <= '9') then
    begin
      number_string = number_string || current_char;
    end
    else if (char_length(number_string) > 0) then
    begin
      -- switching from numeric to non-numeric, found first number occurrence in string
      leave;
    end
  end
  output_value = iif(char_length(number_string) > 0, cast(number_string as bigint), null);
end
...