PL/SQL 用于从 table 的特定列中删除所有特殊字符的代码
PL/SQL code to remove all the special characters from a particular column of a table
我需要使用 PL/SQL 从 table 的特定列中删除所有特殊字符。我们可以使用“REGEXP_SUBSTR”或“REGEXP_REPLACE”来解决这个问题吗?
提前致谢。
问题
这是我的数据的 CSV 格式 -
id,name,location,profession,age
3890,john,melbourne, ,developer,45
2895,david,sydney,ana''lyst,61
5198,kelly,perth,mana@ger,78
7071,tim,canberra,tes/ter,61
8132,mike,brisbane,leader,51
我运行下面的PL/SQL命令删除了所有的特殊字符,但它不起作用-
DECLARE
F UTL_FILE.FILE_TYPE;
V_LINE VARCHAR2 (1000);
V_id VARCHAR2(1000);
V_name VARCHAR2(1000);
V_location VARCHAR2(1000);
V_profession VARCHAR2(1000);
V_age VARCHAR2(1000);
BEGIN
F := UTL_FILE.FOPEN ('DATA_PUMP_DIR', 'person_list.CSV', 'R');
IF UTL_FILE.IS_OPEN(F) THEN
LOOP
BEGIN
UTL_FILE.GET_LINE(F, V_LINE, 1000);
IF V_LINE IS NULL THEN
EXIT;
END IF;
V_id:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 1);
V_name:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 2);
V_location:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 3);
V_profession:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 4);
V_age:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 5);
INSERT INTO person_list VALUES(V_id,V_name,V_location,V_profession,V_age);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
END IF;
UTL_FILE.FCLOSE(F);
END;
/
输出
输出应该是这样的 -
Output of the oracle database without special characters
您可以使用下面的 SQL 查询来获取此输出:
with raw_Text as (select '3890,john,melbourne, ,developer,45' r from dual union all select '2895,david,sydney,ana''lyst,61' from dual union all select '5198,kelly,perth,mana@ger,78' from dual
union all select '7071,tim,canberra,tes/ter,61' from dual
union all select '8132,mike,brisbane,leader,51' from dual ),
cleaned_text as(select regexp_replace(regexp_replace(r,'[^A-Za-z0-9,]',''),',,',',') ct from raw_text)
select substr(ct, 1,instr(ct,',',1,1)-1) id,
substr(ct,instr(ct,',',1,1)+1,instr(ct,',',1,2)-instr(ct,',',1,1)-1) name,
substr(ct,instr(ct,',',1,2)+1,instr(ct,',',1,3)-instr(ct,',',1,2)-1) location,
substr(ct,instr(ct,',',1,3)+1,instr(ct,',',1,4)-instr(ct,',',1,3)-1) profession,
substr(ct,instr(ct,',',1,4)+1) age
from cleaned_text```
--Edit to add PL/SQL code:
DECLARE
F UTL_FILE.FILE_TYPE;
V_LINE VARCHAR2 (32767);
V_id VARCHAR2(1000);
V_name VARCHAR2(1000);
V_location VARCHAR2(1000);
V_profession VARCHAR2(1000);
V_age VARCHAR2(1000);
v_ct varchar2(32767);
BEGIN
F := UTL_FILE.FOPEN ('DATA_PUMP_DIR', 'person_list.CSV', 'R');
IF UTL_FILE.IS_OPEN(F) THEN
LOOP
BEGIN
UTL_FILE.GET_LINE(F, V_LINE, 1000);
IF V_LINE IS NULL THEN
EXIT;
END IF;
v_ct:= regexp_replace(regexp_replace(V_LINE,'[^A-Za-z0-9,]',''),',,',',') ;
v_Id:=substr(ct, 1,instr(ct,',',1,1)-1) ;
v_name:=substr(ct,instr(ct,',',1,1)+1,instr(ct,',',1,2)-instr(ct,',',1,1)-1) ;
v_location:=substr(ct,instr(ct,',',1,2)+1,instr(ct,',',1,3)-instr(ct,',',1,2)-1) ;
v_profession:=substr(ct,instr(ct,',',1,3)+1,instr(ct,',',1,4)-instr(ct,',',1,3)-1) ;
v_age:=substr(ct,instr(ct,',',1,4)+1);
INSERT INTO person_list
values(v_id,v_name,v_location,v_profession,v_age);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
END IF;
UTL_FILE.FCLOSE(F);
END;
/
您可以将包含赋值(v_id
、v_name
...v_age
)和INSERT
语句的行替换为以下
SELECT LISTAGG(''''||REGEXP_REPLACE(
REGEXP_SUBSTR(
v_line,'[^,]+', 1, level
),
'[[:punct:]]'
)||'''',
',') WITHIN GROUP (ORDER BY level)
INTO v_line
FROM (SELECT v_line FROM dual)
CONNECT BY level <= REGEXP_COUNT(v_line, ',') + 1;
EXECUTE IMMEDIATE 'INSERT INTO person_list VALUES('||v_line||')';
您可以使用 REGEXP_REPLACE
.
删除所有标点符号
我需要使用 PL/SQL 从 table 的特定列中删除所有特殊字符。我们可以使用“REGEXP_SUBSTR”或“REGEXP_REPLACE”来解决这个问题吗?
提前致谢。
问题 这是我的数据的 CSV 格式 -
id,name,location,profession,age
3890,john,melbourne, ,developer,45
2895,david,sydney,ana''lyst,61
5198,kelly,perth,mana@ger,78
7071,tim,canberra,tes/ter,61
8132,mike,brisbane,leader,51
我运行下面的PL/SQL命令删除了所有的特殊字符,但它不起作用-
DECLARE
F UTL_FILE.FILE_TYPE;
V_LINE VARCHAR2 (1000);
V_id VARCHAR2(1000);
V_name VARCHAR2(1000);
V_location VARCHAR2(1000);
V_profession VARCHAR2(1000);
V_age VARCHAR2(1000);
BEGIN
F := UTL_FILE.FOPEN ('DATA_PUMP_DIR', 'person_list.CSV', 'R');
IF UTL_FILE.IS_OPEN(F) THEN
LOOP
BEGIN
UTL_FILE.GET_LINE(F, V_LINE, 1000);
IF V_LINE IS NULL THEN
EXIT;
END IF;
V_id:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 1);
V_name:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 2);
V_location:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 3);
V_profession:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 4);
V_age:= REGEXP_SUBSTR(V_LINE, '[^,@,/,'' ]+', 1, 5);
INSERT INTO person_list VALUES(V_id,V_name,V_location,V_profession,V_age);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
END IF;
UTL_FILE.FCLOSE(F);
END;
/
输出 输出应该是这样的 - Output of the oracle database without special characters
您可以使用下面的 SQL 查询来获取此输出:
with raw_Text as (select '3890,john,melbourne, ,developer,45' r from dual union all select '2895,david,sydney,ana''lyst,61' from dual union all select '5198,kelly,perth,mana@ger,78' from dual
union all select '7071,tim,canberra,tes/ter,61' from dual
union all select '8132,mike,brisbane,leader,51' from dual ),
cleaned_text as(select regexp_replace(regexp_replace(r,'[^A-Za-z0-9,]',''),',,',',') ct from raw_text)
select substr(ct, 1,instr(ct,',',1,1)-1) id,
substr(ct,instr(ct,',',1,1)+1,instr(ct,',',1,2)-instr(ct,',',1,1)-1) name,
substr(ct,instr(ct,',',1,2)+1,instr(ct,',',1,3)-instr(ct,',',1,2)-1) location,
substr(ct,instr(ct,',',1,3)+1,instr(ct,',',1,4)-instr(ct,',',1,3)-1) profession,
substr(ct,instr(ct,',',1,4)+1) age
from cleaned_text```
--Edit to add PL/SQL code:
DECLARE
F UTL_FILE.FILE_TYPE;
V_LINE VARCHAR2 (32767);
V_id VARCHAR2(1000);
V_name VARCHAR2(1000);
V_location VARCHAR2(1000);
V_profession VARCHAR2(1000);
V_age VARCHAR2(1000);
v_ct varchar2(32767);
BEGIN
F := UTL_FILE.FOPEN ('DATA_PUMP_DIR', 'person_list.CSV', 'R');
IF UTL_FILE.IS_OPEN(F) THEN
LOOP
BEGIN
UTL_FILE.GET_LINE(F, V_LINE, 1000);
IF V_LINE IS NULL THEN
EXIT;
END IF;
v_ct:= regexp_replace(regexp_replace(V_LINE,'[^A-Za-z0-9,]',''),',,',',') ;
v_Id:=substr(ct, 1,instr(ct,',',1,1)-1) ;
v_name:=substr(ct,instr(ct,',',1,1)+1,instr(ct,',',1,2)-instr(ct,',',1,1)-1) ;
v_location:=substr(ct,instr(ct,',',1,2)+1,instr(ct,',',1,3)-instr(ct,',',1,2)-1) ;
v_profession:=substr(ct,instr(ct,',',1,3)+1,instr(ct,',',1,4)-instr(ct,',',1,3)-1) ;
v_age:=substr(ct,instr(ct,',',1,4)+1);
INSERT INTO person_list
values(v_id,v_name,v_location,v_profession,v_age);
COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN
EXIT;
END;
END LOOP;
END IF;
UTL_FILE.FCLOSE(F);
END;
/
您可以将包含赋值(v_id
、v_name
...v_age
)和INSERT
语句的行替换为以下
SELECT LISTAGG(''''||REGEXP_REPLACE(
REGEXP_SUBSTR(
v_line,'[^,]+', 1, level
),
'[[:punct:]]'
)||'''',
',') WITHIN GROUP (ORDER BY level)
INTO v_line
FROM (SELECT v_line FROM dual)
CONNECT BY level <= REGEXP_COUNT(v_line, ',') + 1;
EXECUTE IMMEDIATE 'INSERT INTO person_list VALUES('||v_line||')';
您可以使用 REGEXP_REPLACE
.