首頁 資料庫 mysql教程 oracel中字符串分割成集合详解

oracel中字符串分割成集合详解

Jun 07, 2016 pm 05:49 PM
字串分割

文章分享一篇关于自己的学习笔记,oracel中字符串分割成集合详解有需要学习的同学可以看看。

首先分别使用两种方式构造两个函数

 代码如下 复制代码

-- use conventional plsql
create or replace function f_str2list_pls
(
  p_str       varchar2,
  p_separator varchar2 default ','
) return my_tk_str_tab_type is
  l_idx  pls_integer := 0;
  l_str  varchar2(32767) := trim(p_str);
  l_elmt varchar2(100) := null;
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
begin
  while l_str is not null loop
    l_idx := instr(l_str, p_separator);
    if l_idx = 0 then
      l_elmt := l_str;
      l_str  := null;
    else
      l_elmt := substr(l_str, 1, l_idx - 1);
      l_str  := substr(l_str, l_idx + 1);
    end if;
 
    l_list.extend;
    l_list(l_list.last) := trim(l_elmt);
  end loop;

  return l_list;
end;
/

-- use single sql
create or replace function f_str2list_sql
(
  p_str       varchar2,
  p_separator varchar2 default ','
) return my_tk_str_tab_type is
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
begin
  substr(a.str,
                instr(p_separator || a.str, p_separator, 1, rn),
                instr(a.str || p_separator, p_separator, 1, rn) -
                instr(p_separator || a.str, p_separator, 1, rn)) q
    bulk collect into l_list
    from (select p_str as str from dual) a,
         (select rownum rn from dual connect by rownum    where instr(p_separator || a.str, p_separator, 1, rn) > 0;

  return l_list;
end;
/

 

 


确认两种方法完成同样的功能

 

----------------------------------------------------

 代码如下 复制代码

-- same result
declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str varchar2(1000) := 'a,b,c';
begin
  l_list := f_str2list_pls(l_str,',');
  for i in 1..l_list.count loop
    dbms_output.put_line(l_list(i));
  end loop;
 
  dbms_output.put_line('');
  l_list := f_str2list_sql(l_str,',');
  for i in 1..l_list.count loop
    dbms_output.put_line(l_list(i));
  end loop;
end;
/

SQL> set serveroutput on
a
b
c
 
a
b
c

 

 

 

 

 

我们知道在PL/SQL和SQL里面,varchar2类型的长度限制是不同的。那么这两种方法是否也存在同样的限制?验证一下

先测试PL/SQL版本

 

-- 这里使用单个字母作为元素,加上必要的逗号分割符,一个元素占用长度2. PL/SQL中上限32767。当取(32767/2 = 16383)个元素的时候,运行成功
----------------------------------------------------

 代码如下 复制代码

-- pls versions tring length limit
declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str  varchar2(32767) := '';
  l_max  pls_integer := 16383;
begin
  -- construct string
  for i in 1 .. l_max loop
    l_str := l_str || ',' || 'a';
  end loop;
  l_str := substr(l_str, 2);

   l_list := f_str2list_pls(l_str, ',');
end;
/

PL/SQL procedure successfully completed

-- 增加一个元素,当取(16384)个元素的时候,超过了varchar2的限制,所以无法运行。(构造字符串就报错了,这个时候其实还没有调用f_str2list_pls)
 代码如下 复制代码

declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str  varchar2(32767) := '';
  l_max  pls_integer := 16384;
begin
  -- construct string
  for i in 1 .. l_max loop
    l_str := l_str || ',' || 'a';
  end loop;

  l_list := f_str2list_pls(l_str, ',');
end;
/

ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 9

-- 修改一下代码,实际调用这个函数。从结果可以看到,f_str2list_pls()内部报超长错误
declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str  varchar2(32767) := '';
  l_max  pls_integer := 16383;
begin
  -- construct string
  for i in 1 .. l_max loop
    l_str := l_str || ',' || 'a';
  end loop;

  l_list := f_str2list_pls(l_str||',a', ',');
end;
 
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "T2.F_STR2LIST_PLS", line 7
ORA-06512: at line 12

 

 

 


下面测试SQL版本

 

 代码如下 复制代码

-- 因为SQL中varchar2上限是4000,所以使用2000个元素。一切正常。
----------------------------------------------------
-- sql versions tring length limit
declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str  varchar2(32767) := '';
  l_max  pls_integer := 2000;
begin
  -- construct string
  for i in 1 .. l_max loop
    l_str := l_str || ',' || 'a';
  end loop;
  l_str := substr(l_str, 2);

   l_list := f_str2list_sql(l_str, ',');
end;
/

PL/SQL procedure successfully completed

-- 直接增加到2001个元素,发现f_str2list_sql()内部报错,说明构造字符串的成功传入,但是函数不能处理
 代码如下 复制代码

declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str  varchar2(32767) := '';
  l_max  pls_integer := 2001;
begin
  -- construct string
  for i in 1 .. l_max loop
    l_str := l_str || ',' || 'a';
  end loop;
  l_str := substr(l_str, 2);

   l_list := f_str2list_sql(l_str, ',');
end;
 
ORA-01460: unimplemented or unreasonable conversion ed
ORA-06512: at "T2.F_STR2LIST_SQL", line 8
ORA-06512: at line 13

备注:ORA-01460的描述很不清楚,其实这里就是varchar2超长

 

 

 

 

 

测试比较两种方式在不同数据量下的性能

 

 代码如下 复制代码

----------------------------------------------------
-- performance test
declare
  l_list my_tk_str_tab_type := my_tk_str_tab_type();
  l_str  varchar2(32767) := '';
  l_max  pls_integer := 2000;
begin
  -- construct string
  for i in 1 .. l_max loop
    l_str := l_str || ',' || 'a';
  end loop;
  l_str := substr(l_str, 2);

  -- warm up before actually calculation
  l_list := f_str2list_sql(l_str, ',');
  l_list := f_str2list_pls(l_str, ',');
 
  -- begin calc and diff
  my_rs.rs_start;
  -- 1. pls version
  l_list := f_str2list_pls(l_str, ',');
  my_rs.rs_middle;
  -- 2. sql version
  l_list := f_str2list_sql(l_str, ',');
  my_rs.rs_stop();
end;
/

 

 

 


我们分别测试当元素个数为100, 200, 500, 1000, 2000的情况。每种情况进行3-5次然后取平均

元素个数

PL/SQL 运行时间 (1/100 second)

SQL 运行时间 (1/100 second)

PCT

100

1

1

100%

200

1

1 - 2

50% - 100%

500

1 - 2

2 - 3

30% - 50%

1000

1

4

25%

2000

2

10

20%

总结:

SQL版本的书写简便,并且可以脱离PL/SQL环境直接使用(单条SQL进行行列转换)。

SQL版本只能处理长度小于4000的字符串,实际最大只能包含2000个元素。PL/SQL版本可以处理长度小于32767的字符串。

小数据量情况下,两者性能相当。随着数据量增大,PL/SQL版本性能明显占优

 

 

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora:巫婆樹的耳語 - 如何解鎖抓鉤
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1666
14
CakePHP 教程
1425
52
Laravel 教程
1324
25
PHP教程
1272
29
C# 教程
1251
24
Python 3.x 中如何使用split()函數將字串依照指定分隔符號分割 Python 3.x 中如何使用split()函數將字串依照指定分隔符號分割 Jul 31, 2023 pm 08:33 PM

Python是一種流行的程式語言,它提供了許多內建函數來處理字串。其中一個常用的函數是split()函數,可以依照指定的分隔符號將字串分割成多個子字串。本文將介紹如何在Python3.x中使用split()函數。在Python中,split()函數是字串類別的一個內建函數,它的基本語法如下:string.split(separator,maxsplit)

PHP中如何使用explode函數分割字串 PHP中如何使用explode函數分割字串 Jun 26, 2023 pm 12:03 PM

在PHP語言中,有許多基礎函數可以幫助我們快速有效地處理字串。其中,explode函數是一個很實用的字串分割函數。它可以將一個字串依照指定的分割符分割成數組,進而進行更靈活的字串操作。在本文中,我們將會介紹PHP中如何使用explode函數來分割字串。一、explode函數格式explode函數在PHP語言的格式如下:explode(separa

字串的最大分割長度,使得字串中的每個字元都出現在一個子字串中 字串的最大分割長度,使得字串中的每個字元都出現在一個子字串中 Aug 25, 2023 pm 02:41 PM

在本文中,我們將探討如何找到具有唯一字元的字串的最大化分區的長度問題。我們首先了解問題陳述,然後研究解決這個問題的樸素和高效方法,包括它們各自的演算法和時間複雜度。最後,我們將在C++中實作解決方案。問題陳述給定一個字串,將字串分割為盡可能多的子字串,使得字串中的每個字元只出現在一個子字串中。傳回這些最大化分割的長度。天真的方法天真的方法是透過字串迭代,記錄每個字元的最後出現位置。然後,再次迭代字串,並在找到當前字元的最後出現位置時建立分區。演算法(樸素)初始化一個陣列以儲存字串中

如何在PHP中將字串分割為數組 如何在PHP中將字串分割為數組 Jul 08, 2023 pm 01:49 PM

如何在PHP中將字串分割為陣列在PHP中,我們經常需要處理字串,並將其拆分為多個部分。將字串分割為陣列是一種常見的操作,可以幫助我們更好地處理字串的各個部分。在本文中,我們將學習如何使用PHP中的函數將字串分割為數組,並提供一些程式碼範例。使用explode函數將字串分割成陣列PHP提供了一個名為explode的函數,可以將字串依照指定的分隔符號進

計算將字串分割為以偶數開頭且最小長度為M的K個子字串的方法數 計算將字串分割為以偶數開頭且最小長度為M的K個子字串的方法數 Sep 09, 2023 pm 02:01 PM

在這個問題中,我們將計算將給定的字串劃分為K個子字串的方法,使其滿足問題陳述中給出的條件。我們將使用遞歸來解決這個問題。此外,我們還將使用表格動態規劃方法來有效解決這個問題。問題陳述−我們有一個名為bin_Str的特定長度的字串。該字串只包含從'0'到'9'的數字字元。我們需要計算將字串分割成K個子字串的方式數,使其滿足以下條件。子字串應至少包含2個字元。每個子字串的第一個字元應為偶數,最後一個字元應為奇數。範例範例輸入M=2,K=2;bin_str="255687&q

檢查一個字串是否可以分割成三個子字串,其中一個子字串是另外兩個子字串的子字串 檢查一個字串是否可以分割成三個子字串,其中一個子字串是另外兩個子字串的子字串 Sep 22, 2023 am 11:53 AM

在這個問題中,我們需要分割給定的字串,使得第三個子字串可以是前兩個子字串的子字串。讓我們想想解決辦法。僅當兩個字串包含第三個字串的所有字元時,第三個字串才可以是前兩個字串的子字串。所以,我們需要在給定的字串中找到至少一個出現頻率大於3的字符,並且我們可以取該單一字符的第三個子串。問題陳述-我們給了一個包含N個小寫字母字元的字串str。我們需要檢查是否可以將字串拆分為三個子字串a、b和c,使得子字串c是a和b的子字串。根據是否能找到3個子串,印出“yes”或“no

解PHP中explode函數報錯的方法 解PHP中explode函數報錯的方法 Mar 11, 2024 am 11:45 AM

解決PHP中explode函數報錯的方法,需要具體程式碼範例在PHP中,explode函數是用來將字串依照指定的分隔符號拆分成數組的函數。然而,有時在使用explode函數時會出現報錯的情況,主要是因為傳入的參數不符合函數的要求所導致的。以下我們將針對可能出現的問題和解決方法進行詳細討論,並提供具體的程式碼範例。參數個數錯誤導致的錯誤當使用explode函數

PHP字串函數實例:字串分割 PHP字串函數實例:字串分割 Jun 20, 2023 pm 01:58 PM

PHP中有許多字串函數,其中字串分割函數是非常常用的。字串分割函數可以將字串依照指定的分隔符號分割,並傳回一個陣列。下面我們就來介紹幾個常用的字串分割函數。 explode函數explode函數可以將字串依照指定的分隔符號分割,並傳回一個陣列。其語法如下:explode(string$separator,string$string

See all articles