如何计算oracle中从一个字符到另一个字符的子字符串的长度

Posted

技术标签:

【中文标题】如何计算oracle中从一个字符到另一个字符的子字符串的长度【英文标题】:how to count the length of a substring from one character to other in oracle 【发布时间】:2015-04-22 06:03:22 【问题描述】:

我必须从 sql (Oracle 11g) 中的字符串更新子字符串的长度

从这里>> #L1313.0000002.CGNMC到这里>> #L1313.0000000002.CGNMC

我想计算点(。)之间的字符串长度,如果它小于 10,那么我想附加尽可能多的零以使其变为 10

计算字符串的整个长度并没有帮助,因为更改只能在子字符串中完成。

请帮忙

【问题讨论】:

【参考方案1】:
select lpad(substr('#L1313.0000002.CGNMC',
                   instr('#L1313.0000002.CGNMC','.') + 1,
                   instr('#L1313.0000002.CGNMC','.',1,2) -
                     instr('#L1313.0000002.CGNMC','.') - 1),
            10, '0') from dual; 

lpad('x',10,'0') - 将 char '0' 添加到字符串 'x' 中,最大为 10

substr(string, start, length) - 返回子字符串

instr(string,substring[,start[,occurence]]) - 返回字符串中子字符串的位置。 start 是搜索的起点,occurrence 表示搜索第 n 次出现的字符串。

参见 oracle 文档https://docs.oracle.com/cd/E11882_01/server.112/e41084/functions.htm#SQLRF006

【讨论】:

您的解决方案不完整。 OP 只想在点之间的 substr 的长度小于 10 时才这样做。 @LalitKumarB 可能是的。该问题未指定点之间是否有超过 10 个字符的数据。在这种情况下,我会添加 CASE...WHEN ... ELSE 类似于您的示例 是的,这就是我想要指出的。当字符串已经有超过 10 个字符时,您将其强制为 10。无论如何,希望它有所帮助:-)【参考方案2】:

我用过update、instr和substr

update table set column_name= case
when (instr(column_name,'.',1,2)-instr(column_name,'.',1,1)-1)<10 then substr(column_name,0,instr(column_name,'.',1,1))||lpad(substr(column_name,instr(column_name,'.',1,1)+1,instr(column_name,'.',1,2)-instr(column_name,'.',1,1)-1),10,'0')||substr(column_name,instr(column_name,'.',1,2))
end
;

查看以下查询以获取演示

select substr('L1313.0000002.CGNMC',0,instr('L1313.0000002.CGNMC','.',1,1))||lpad(substr('L1313.0000002.CGNMC',instr('L1313.0000002.CGNMC','.',1,1)+1,instr('L1313.0000002.CGNMC','.',1,2)-instr('L1313.0000002.CGNMC','.',1,1)-1),10,'0')||substr('L1313.0000002.CGNMC',instr('L1313.0000002.CGNMC','.',1,2)) from dual;

【讨论】:

【参考方案3】:

你可以通过以下组合来做到这一点:

SUBSTR INSTR 案例 解码

以下查询是如何工作的:

SUBSTR 会给我字符串的一部分,INSTR 会给我点的位置。 CASE 是检查点之间子字符串长度的条件,最后 DECODE 会让我做最后的工作来附加所需的零。

测试用例

我正在考虑所有可能的情况。

SQL> WITH DATA AS
  2    ( SELECT '#L1313.0000002.CGNMC' str FROM dual UNION ALL
  3    SELECT '#L1313.002.CGNMC' str FROM dual UNION ALL
  4    SELECT '#L1313.00123.CGNMC' str FROM dual UNION ALL
  5    SELECT '#L1313.12345.CGNMC' str FROM dual UNION ALL
  6    SELECT '#L1313.12345678910.CGNMC' str FROM dual
  7    )
  8  SELECT str,
  9    CASE
 10      WHEN instr(str, '.', 1, 2)         - instr(str, '.', 1, 1) -1 < 10
 11      THEN DECODE((instr(str, '.', 1, 2) - instr(str, '.', 1, 1) -1),
 12                                                   9, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 13        ||'0'
 14        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 8, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 15        ||'00'
 16        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 7, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 17        ||'000'
 18        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 6, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 19        ||'0000'
 20        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 5, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 21        ||'00000'
 22        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 4, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 23        ||'000000'
 24        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 3, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 25        ||'0000000'
 26        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 2, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 27        ||'00000000'
 28        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)), 1, (SUBSTR(str, 1, instr(str, '.', 1, 1))
 29        ||'000000000'
 30        ||SUBSTR(str, instr(str, '.', 1, 1) + 1)) )
 31      ELSE
 32        str
 33    END new_str
 34  FROM DATA;

STR                      NEW_STR
------------------------ ---------------------------------------------
#L1313.0000002.CGNMC     #L1313.0000000002.CGNMC
#L1313.002.CGNMC         #L1313.0000000002.CGNMC
#L1313.00123.CGNMC       #L1313.0000000123.CGNMC
#L1313.12345.CGNMC       #L1313.0000012345.CGNMC
#L1313.12345678910.CGNMC #L1313.12345678910.CGNMC

SQL>

【讨论】:

【参考方案4】:

我已经编写了一个可以完成工作的函数,请检查它是否适合你。

SQL>    create or replace function paddingstr1( inval varchar2) return varchar2 is
  2     lval varchar2(100):=inval;
  3     final_str varchar2(100);
  4     str3 varchar2(100);
  5     str2 varchar2(100);
  6     str1 varchar2(100);
  7     lpad_str varchar2(100);
  8     pos1 int;
  9     pos2 int;
 10     getval int;
 11     begin
 12     select instr(lval,'.') into pos1 from dual;
 13     select instr(lval,'.',1,2) into pos2 from dual;
 14     getval:=pos2-pos1-1;
 15     pos1:=pos1+1;
 16     select substr(lval,pos1,getval) into lpad_str from dual;
 17     select lpad(lpad_str,10,'0')  into str2 from dual;
 18     select substr(lval,1,pos1-1) into str1 from dual;
 19     select substr(lval,pos2) into str3 from dual;
 20     final_str:= concat (str1,concat (str2,str3));
 21     return final_str;
 22     end;
 23  /

Function created.

SQL> select paddingstr1('#L1313.0000002.CGNMC') from dual;

PADDINGSTR1('#L1313.0000002.CGNMC')
--------------------------------------------------------------------------------
#L1313.0000000002.CGNMC

SQL> select paddingstr1('#LAD313.002.ERGH') from dual;

PADDINGSTR1('#LAD313.002.ERGH')
------------------------------------------------------------
#LAD313.0000000002.ERGH

【讨论】:

以上是关于如何计算oracle中从一个字符到另一个字符的子字符串的长度的主要内容,如果未能解决你的问题,请参考以下文章

40 python 正则表达式 match方法匹配字符串 使用search函数在一个字符串中查找子字

在Ruby中从末尾切片字符串

在 Oracle (> 11g) 中从逗号分隔列表创建表 - 输入字符串限制 4000 个字符

字符串s中从第i个位置起取长度为len的子串,函数返回子串链表

oracle如何从查询字符串中进行选择

熊猫在一个系列中从另一个系列中找到超级字符串