plsql 类似Java中的split方法 字符串分割

本文详细介绍了资产形成API的结构与功能,包括类型定义、常量设置、字符串分割函数、验收单验证过程等核心内容。通过实例展示了如何利用API进行资产验收单的建卡操作,提供了一个实用的技术解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

--包头
CREATE OR REPLACE PACKAGE asset_formation_api IS

  -- Author  : DIQYE
  -- Created : 2012/11/8 10:40:38
  -- Purpose : dd
  
  TYPE check_bill_id_table IS TABLE OF VARCHAR2(30) 
	INDEX BY BINARY_INTEGER;

  constant_name CONSTANT VARCHAR2(10) := 'ddddd';
	-- 分割符
	split_code CONSTANT CHAR := ',';
	--已建卡
	created_card CONSTANT NUMBER(1) := 0;
	--未建卡
	not_create_card CONSTANT NUMBER(1) := 1;
	--分割字符串 以逗号分割
  FUNCTION str_split(str IN VARCHAR2) RETURN check_bill_id_table;
	
	--验证这些这些验收单的系统验收单是否已经建卡
	--已建卡 check_result = 0
	--未建卡 check_result = 1
	PROCEDURE check_parent(str IN VARCHAR2, check_result OUT NUMBER);

END asset_formation_api;


包体

create or replace package body asset_formation_api is

	current_p INTEGER; --当前字符串的位置
	last_p INTEGER := 1; -- 上次逗号出现的位置
	str_num INTEGER :=1; --截取字符串的数量  没截取一次加一
	FUNCTION nextStr(str IN VARCHAR2) RETURN VARCHAR2;
	PROCEDURE init IS
		BEGIN
			current_p := 1;
			last_p := 1;
			str_num := 1;
		END;
  -- Public function and procedure declarations
	--分割字符串 以逗号分割
  FUNCTION str_split(str IN VARCHAR2) RETURN  check_bill_id_table
	IS
     i INTEGER := 1; --集合下标
		 reslt asset_formation_api.check_bill_id_table; --返回结果
		 param VARCHAR2(2000);
		 s VARCHAR2(100); --分割之后的 单个的字符串
	BEGIN
		init;
		param := TRIM(str)||',';

		LOOP 
			    s := nextStr(param);
					EXIT WHEN s IS NULL;
				  reslt(i) := s;
					i := i+1;
		END LOOP;
	   RETURN reslt;
	END;
	
	--验证这些这些验收单的系统验收单是否已经建卡
	--已建卡 check_result = 0
	--未建卡 check_result = 1
	PROCEDURE check_parent(str IN VARCHAR2, check_result OUT NUMBER)
		IS
		
		BEGIN
			NULL;
		END;
		
		
	FUNCTION nextStr(str IN VARCHAR2) RETURN VARCHAR2
		IS
		    reslt VARCHAR2(100);
				sp_p INTEGER; --逗号在str中出现的第last_p个位置
		BEGIN 
      sp_p := instr(str, split_code,1,str_num); 	
		  IF sp_p = 0 THEN
				reslt := NULL;
			ELSIF str_num = 1 THEN
			      reslt := substr(str, last_p,sp_p-last_p);
			ELSE
			  reslt := substr(str, last_p+1,sp_p-last_p-1);
			END IF;	
			last_p := sp_p;
			str_num := str_num + 1;
			RETURN reslt;
		END;
end asset_formation_api;



<think>好的,我现在需要帮助用户解决在PL/SQL中如何分割同一字段中逗号连接的字符串并转为行的问题。首先,我得回想一下PL/SQL中处理字符串分割的常用方法。用户提到的是逗号分隔的字符串,所以核心问题是将这样的字符串拆分成多行,每一行对应原来的一个元素。 首先,我应该考虑使用Oracle的内置函数。可能的方法包括使用CONNECT BY子句结合正则表达式,或者使用XMLTABLE函数。另外,递归查询也是一个可行的选项,尤其是对于较老版本的Oracle,可能不支持较新的函数。 接下来,我需要验证这些方法的具体实现。例如,使用REGEXP_SUBSTR配合CONNECT BY LEVEL的方法。这里的关键是生成行号,然后通过正则表达式逐个提取元素。需要注意的是,如何正确终止循环,避免生成多余的空行。通常可以通过检查是否提取到值,或者使用正则表达式计算元素的总数,然后通过LEVEL <= 总数来控制循环次数。 比如,用户提供的示例数据是'apple,banana,orange',期望输出三行。我需要确保查询能够正确分割这三个元素。可能遇到的问题包括逗号后的空格,但用户例子中没有空格,所以暂时不需要处理这种情况,但可能需要提醒用户注意数据中的可能空格。 另一种方法是使用XMLTABLE,将字符串转换为XML格式,然后通过XPath进行分割。这种方法可能更简洁,但需要了解XML函数的使用方式。例如,替换逗号为XML标签,然后解析。不过,如果原始字符串中包含特殊字符如<或&,可能会导致问题,需要转义处理,但用户例子中是简单字符串,可能不需要考虑这点。 递归查询的方法可能适用于更复杂的情况,比如元素数量不确定,逐层拆分。但对于简单的逗号分隔,可能稍微繁琐。不过,这可以作为另一种解决方案提供给用户。 另外,需要考虑Oracle版本。如果用户使用的是11g或更早版本,某些函数可能不可用,而12c及以上版本可能有更优化的方法。但通常REGEXP_SUBSTR和CONNECT BY在较老的版本中也是支持的,所以这可能是一个通用的解决方案。 然后,我需要组织这些方法,按步骤解释,确保用户能够理解每个步骤的作用。例如,在第一种方法中,使用正则表达式分割,并生成行号,可能需要解释CONNECT BY LEVEL的作用,以及REGEXP_SUBSTR的参数如何工作。同时,提醒用户注意性能问题,如果字符串很长或数据量很大,可能需要优化。 最后,可能需要提供示例代码,并说明如何将其嵌入到PL/SQL的存储过程或查询中,比如在SELECT语句中使用这些方法,或者在游标中处理。此外,如果用户需要在更新或插入时使用此转换,可能需要不同的处理方式。 总结下来,我应该分步骤介绍两种主要方法:使用正则表达式和CONNECT BY,以及使用XMLTABLE,可能再加上递归查询。每种方法给出示例代码,解释其原理,并指出注意事项和适用场景。这样用户可以根据自己的实际情况选择最合适的方法。</think>在PL/SQL中,将逗号分隔的字符串拆分为多行记录可以通过以下方法实现,具体分步骤说明如下: --- ### 方法一:使用 `REGEXP_SUBSTR` + `CONNECT BY` **步骤说明**: 1. 通过正则表达式匹配分隔符 2. 使用层级查询生成行号 3. 按位置提取子字符串 ```sql SELECT TRIM(REGEXP_SUBSTR(str, '[^,]+', 1, LEVEL)) AS split_value FROM (SELECT 'apple,banana,orange' AS str FROM dual) CONNECT BY LEVEL <= REGEXP_COUNT(str, ',') + 1 AND PRIOR SYS_GUID() IS NOT NULL AND PRIOR str = str; ``` **关键点解析**: - `REGEXP_SUBSTR(str, '[^,]+', 1, LEVEL)`:从第1个字符开始,按层级提取非逗号内容 - `REGEXP_COUNT(str, ',') + 1`:计算分隔后的元素总数 - `PRIOR`条件:防止循环查询产生笛卡尔积 --- ### 方法二:使用 `XMLTABLE` 转换 **步骤说明**: 1. 将逗号替换为XML标签 2. 通过XML解析拆分字符串 ```sql SELECT x.column_value.getstringval() AS split_value FROM XMLTABLE(('"' || REPLACE('apple,banana,orange', ',', '","') || '"')) AS x; ``` **关键点解析**: - `REPLACE`将逗号转换为`","`,构建XML格式字符串 - `XMLTABLE`解析为多行记录 --- ### 方法三:递归子查询(Oracle 11g+) **步骤说明**: 1. 递归查找逗号位置 2. 逐层截取字符串 ```sql WITH split_cte (str, start_pos, end_pos) AS ( SELECT 'apple,banana,orange', 1, INSTR('apple,banana,orange', ',', 1) FROM dual UNION ALL SELECT str, end_pos + 1, INSTR(str, ',', end_pos + 1) FROM split_cte WHERE end_pos > 0 ) SELECT CASE WHEN end_pos > 0 THEN SUBSTR(str, start_pos, end_pos - start_pos) ELSE SUBSTR(str, start_pos) END AS split_value FROM split_cte; ``` --- ### 注意事项 1. **空值处理**:若原字符串包含连续逗号(如`a,,b`),需增加`NULLIF`过滤空值 2. **性能优化**:大数据量时优先选择`REGEXP`方法,小数据量可选`XMLTABLE` 3. **特殊字符**:若包含XML敏感符号(如`<`),需用`DBMS_XMLGEN.CONVERT`转义 --- ### 扩展场景 若需在存储过程中使用,可封装为函数: ```sql CREATE OR REPLACE FUNCTION split_string( p_str IN VARCHAR2, p_delim IN VARCHAR2 DEFAULT ',' ) RETURN SYS.ODCIVARCHAR2LIST IS l_result SYS.ODCIVARCHAR2LIST := SYS.ODCIVARCHAR2LIST(); BEGIN SELECT TRIM(REGEXP_SUBSTR(p_str, '[^'||p_delim||']+', 1, LEVEL)) BULK COLLECT INTO l_result FROM dual CONNECT BY LEVEL <= REGEXP_COUNT(p_str, p_delim) + 1; RETURN l_result; END; / ``` **调用方式**: ```sql SELECT * FROM TABLE(split_string('apple,banana,orange')); ``` 通过以上方法,可灵活处理PL/SQL中字符串拆分需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值