sql - 我可以在 Firebird POSITION 函数中使用通配符吗
问题描述
我正在使用火鸟 2.1。
我的工作订单号可能有 1 个或 2 个字母字符,然后是 4 个或 5 个数字,然后可能是一个带有 1 个字母字符和 2 个数字的前缀。
我想提取中间的4-5位数字。
我尝试了以下方法来查找数字字符,但它返回 0:
POSITION('%[0-9]%',JOBHEADER.ORDERNUMBER,1) AS "FIRST NUMBER"
我不确定是否可以在该POSITION
函数中使用通配符。我想我可以尝试检查数字的第二个或第三个字符,但我真的需要通配符功能,然后在找到第一个数字的位置后找到下一个字母。或者也许有另一种解决方案来提取数字。
我发现了一些类似的东西:
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 语句开始变得非常大。
解决方案
不,你不能用POSITION
. 位置搜索给定字符串中的确切子字符串。但是,使用 Firebird 3,您可以使用SUBSTRING
正则表达式来提取值,例如:
substring(ordernumber similar '%#"[[:DIGIT:]]+#"%' escape '#')
正则表达式必须覆盖整个字符串,而#"
包含要提取的术语(the#
是显式定义的转义符号)。您可能需要使用更复杂的模式,例如[^[:DIGIT:]]*#"[[:DIGIT:]]+#"([^[:DIGIT:]]%)?
避免贪婪的边缘情况。
如果您知道模式始终是 1 或 2 个 alpha、4 或 5 个要提取的数字,可能后跟 1 个 alpha 和 2 个数字,您也可以使用[[:ALPHA:]]{1,2}#"[[:DIGIT:]]{4,5}#"([[:ALPHA:]][[:DIGIT:]]{1,2})?
. 如果模式不匹配null
,则返回。
也可以看看:
请注意,Firebird 支持的 SQL 标准正则表达式语法有点奇怪,并且不如其他语言中常见的正则表达式强大。
使用 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
推荐阅读
- laravel-8 - Laravel 8 控制器构造函数中的类型提示请求?
- python - 有没有办法使用 python 在不同的 Outlook 附件中搜索用户定义的字符串?
- openssh - ssh - 私钥文件在文件末尾需要 \n 或导致“加载密钥 id_rsa 格式无效”
- linux - Bash脚本使用变量传递带有空格的参数
- flutter - 如何从屏幕上永久删除小部件
- python - 为什么我的 for 循环打印列表 n 次?
- squarespace - Squarespace 中的标题自定义
- node.js - 如何在具有限制的 Mongoose 数组对象中应用条件
- spring - 在 sprinboot stomp websocket 中使用原因 SESSION_NOT_RELIABLE(4500) 断开会话
- laravel - 尝试创建新目录时出现“mkdir():权限被拒绝” - laravel