Нет, вы не можете сделать это с 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