将管道分隔的字符串解析为列?

发布于 2024-09-03 22:24:15 字数 248 浏览 6 评论 0原文

我有一列包含管道分隔值,例如:

'23|12.1| 450|30|9|78|82.5|92.1|120|185|52|11'

我想解析此列以用 12 个相应列填充表:month1、month2、month3...month12。

因此,month1 的值为 23,month2 的值为 12.1 等...

有没有一种方法可以通过循环或分隔符来解析它,而不必使用 substr 一次分隔一个值?

谢谢。

I have a column with pipe separated values such as:

'23|12.1| 450|30|9|78|82.5|92.1|120|185|52|11'

I want to parse this column to fill a table with 12 corresponding columns: month1, month2, month3...month12.

So month1 will have the value 23, month2 the value 12.1 etc...

Is there a way to parse it by a loop or delimeter instead of having to separate one value at a time using substr?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苹果你个爱泡泡 2024-09-10 22:24:15

您可以使用regexp_substr(10g+):

SQL> SELECT regexp_substr('23|12.1| 450|30|9|', '[^|]+', 1, 1) c1,
  2         regexp_substr('23|12.1| 450|30|9|', '[^|]+', 1, 2) c2,
  3         regexp_substr('23|12.1| 450|30|9|', '[^|]+', 1, 3) c3
  4    FROM dual;

C1 C2   C3
-- ---- ----
23 12.1  450

在PL/SQL中使用循环:

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2     p_tsv  VARCHAR2(1000) := '23|12.1| 450|30|9|78|82.5|92.1|120|185|52|11';
  3     l_item VARCHAR2(100);
  4  BEGIN
  5     FOR i IN 1 .. length(p_tsv) - length(REPLACE(p_tsv, '|', '')) + 1 LOOP
  6        l_item := regexp_substr(p_tsv, '[^|]+', 1, i);
  7        dbms_output.put_line(l_item);
  8     END LOOP;
  9  END;
 10  /

23
12.1
450
30
9
78
82.5
92.1
120
185
52
11

PL/SQL procedure successfully completed

更新

只有有12列,我会直接编写查询而无需循环,它将是比动态 SQL 性能更高、更容易维护(更不用说更容易编写):

INSERT INTO your_table
   (ID, month1, month2, month3...)
   SELECT :p_id, 
          regexp_substr(:p_tsv, '[^|]+', 1, 1) c1, 
          regexp_substr(:p_tsv, '[^|]+', 1, 2) c2,
          regexp_substr(:p_tsv, '[^|]+', 1, 3) c3
          ...
     FROM dual;

You can use regexp_substr (10g+):

SQL> SELECT regexp_substr('23|12.1| 450|30|9|', '[^|]+', 1, 1) c1,
  2         regexp_substr('23|12.1| 450|30|9|', '[^|]+', 1, 2) c2,
  3         regexp_substr('23|12.1| 450|30|9|', '[^|]+', 1, 3) c3
  4    FROM dual;

C1 C2   C3
-- ---- ----
23 12.1  450

With a loop in PL/SQL:

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2     p_tsv  VARCHAR2(1000) := '23|12.1| 450|30|9|78|82.5|92.1|120|185|52|11';
  3     l_item VARCHAR2(100);
  4  BEGIN
  5     FOR i IN 1 .. length(p_tsv) - length(REPLACE(p_tsv, '|', '')) + 1 LOOP
  6        l_item := regexp_substr(p_tsv, '[^|]+', 1, i);
  7        dbms_output.put_line(l_item);
  8     END LOOP;
  9  END;
 10  /

23
12.1
450
30
9
78
82.5
92.1
120
185
52
11

PL/SQL procedure successfully completed

Update

You only have 12 columns, I would write the query direcly without a loop, it will be more performant and easier to maintain than dynamic SQL (not to mention infinitely easier to write):

INSERT INTO your_table
   (ID, month1, month2, month3...)
   SELECT :p_id, 
          regexp_substr(:p_tsv, '[^|]+', 1, 1) c1, 
          regexp_substr(:p_tsv, '[^|]+', 1, 2) c2,
          regexp_substr(:p_tsv, '[^|]+', 1, 3) c3
          ...
     FROM dual;
愁杀 2024-09-10 22:24:15

我认为没有什么已经定义的东西。

orafaq 上几乎没有实现,我发现这个也是。

I don't think there's something already defined.

There are few implementations at orafaq and I found this also.

╄→承喏 2024-09-10 22:24:15

我有99个问题
所以我使用了正则表达式
现在我有100个问题
哈哈哈哈哈哈
只需将 delim 连接到开始和;字符串末尾

纯sql解决方案:

set define on
undefine string
undefine delim
undefine nth
accept string prompt 'Enter the string: '
accept delim prompt 'Enter the delimiter: '
accept nth prompt 'Enter nth: '
select '&&string' as string,
       '&&delim' as delimiter, 
        &&nth||decode(&&nth,1,'st',2,'nd',3,'rd','th') as nth,
 substr('&&delim'||'&&string'||'&delim',
        instr('&&delim'||'&&string'||'&&delim', '&&delim', 1, &&nth ) + length('&&delim'),
        instr('&&delim'||'&&string'||'&&delim', '&&delim', 1, &&nth + 1 ) - instr('&&delim'||'&&string'||'&&delim', '&&delim', 1, &&nth ) - length('&&delim')
       ) as val from dual

/

I had 99 problems
So I used regular expressions
Now I have 100 problems
hahahahahahaha
just concatenate the delim onto beginning & end of string

pure sql solution:

set define on
undefine string
undefine delim
undefine nth
accept string prompt 'Enter the string: '
accept delim prompt 'Enter the delimiter: '
accept nth prompt 'Enter nth: '
select '&&string' as string,
       '&&delim' as delimiter, 
        &&nth||decode(&&nth,1,'st',2,'nd',3,'rd','th') as nth,
 substr('&&delim'||'&&string'||'&delim',
        instr('&&delim'||'&&string'||'&&delim', '&&delim', 1, &&nth ) + length('&&delim'),
        instr('&&delim'||'&&string'||'&&delim', '&&delim', 1, &&nth + 1 ) - instr('&&delim'||'&&string'||'&&delim', '&&delim', 1, &&nth ) - length('&&delim')
       ) as val from dual

/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文