.....
temp Varchar2 (20);
e_name Varchar2 (255);
.....
Begin
e_name := e_name || temp;
Dbms_Output.Put_Line('names: ' || e_name);
Output result
-------------
names: 'John', 'Sam', 'David', 'Sam', 'John', 'Alex'
如何格式化我的e_name以删除重复的名称,以便我有输出结果
required result
-------------
names: 'John', 'Sam', 'David', 'Alex'
答案 0 :(得分:1)
你可以像这样修改你的程序
Begin
e_name := e_name || temp;
SELECT listagg ( names, ',' ) within GROUP (ORDER BY rn )
INTO e_name
FROM
(
SELECT level rn,
regexp_substr ( e_name, '[^,]+', 1, level ) names,
row_number ( ) over ( partition BY regexp_substr ( e_name, '[^,]+', 1, level ) order by level ) rnn
FROM dual
CONNECT BY regexp_substr ( e_name, '[^,]+', 1, level ) IS NOT NULL
)
WHERE rnn = 1;
Dbms_Output.Put_Line('names: ' || e_name);
最内层的查询会将列表转换为行,然后外部查询将过滤并再次创建字符串。
答案 1 :(得分:1)
用LISTAGG替换WM_CONCAT - 我正在运行Oracle 10g,LISTAGG是11g:
SELECT wm_concat(ename) AS employees
FROM emp_test
WHERE deptno = 20
/
Output - SMITH repeats twice:
SMITH,JONES,SCOTT,ADAMS,FORD,SMITH
SELECT wm_concat(distinct ename) AS employees
FROM emp_test
WHERE deptno = 20
/
The distinct fixes the problem:
ADAMS,FORD,JONES,SCOTT,SMITH
答案 2 :(得分:0)
这可以在纯SQL中完成,但它有点乱,特别是如果你是11gR2之前的listagg()。由于您已经处于PL / SQL领域,因此这是一种以简单的PL / SQL方式消除重复的解决方案:
declare e_name varchar2(255) := q'"'John', 'Sam', 'David', 'Sam', 'John', 'Alex'"';
new_ename varchar2(255) := substr(e_name,1,instr(e_name,'''',2));
begin
dbms_output.put_line ('e_name: ' || e_name);
for i in 1..length(e_name) - length(replace(e_name,',')) loop
if instr(new_ename,
substr(e_name,instr(e_name,', ',1,i),instr(e_name||', ',', ',1,i+1) - instr(e_name,', ',1,i))) = 0
then
new_ename := new_ename || substr(e_name,instr(e_name,', ',1,i),instr(e_name||', ',', ',1,i+1) - instr(e_name,', ',1,i));
end if;
end loop;
dbms_output.put_line ('new_ename: ' || new_ename);
end;
e_name: 'John', 'Sam', 'David', 'Sam', 'John', 'Alex'
new_ename: 'John', 'Sam', 'David', 'John', 'Alex'
答案 3 :(得分:0)
有一些名为ASSOCIATIVE的数组,它在Java中充当哈希表。我们可以将分隔文本放入哈希表中,从而可以消除重复项。
我们在这里使用EXISTS收集方法来检查该值是否已经存在!
这是一个简单易读的 NO SQL 类型的解决方案。所以,执行一个。
DECLARE
e_name VARCHAR2 (4000) := 'the text goes here';
L_TEMP_TEXT VARCHAR2(4000);
V_LOOPCOUNT NUMBER :=0;
T_WORD VARCHAR2(4000);
T_FINAL_TEXT VARCHAR2(4000) := ' ';
--Declare a DICT like a Hash table
TYPE DICT IS TABLE OF VARCHAR2(4000) INDEX BY VARCHAR(4000);
MYDICT DICT;
BEGIN
L_TEMP_TEXT := regexp_replace(e_name,'[,]+',','); -- Replace multiple consecutive commas as single
LOOP
v_LOOPCOUNT := v_LOOPCOUNT+1;
T_WORD := REGEXP_SUBSTR(e_name, '[^,]+', 1, V_LOOPCOUNT);
--In a loop we tokenize the String using comma as delimiter
EXIT WHEN T_WORD IS NULL;
IF NOT MYDICT.EXISTS(T_WORD) THEN
-- It is like a Hash Table, if not exists add to it.
MYDICT(T_WORD) := T_WORD;
T_FINAL_TEXT : T_FINAL_TEXT || ',' || T_WORD;
END;
END LOOP;
T_FINAL_TEXT := TRIM(BOTH ',' FROM TRIM(T_FINAL_TEXT));
-- Trimming the unwanted commas
DBMS_OUTPUT.PUT_LINE('after removing duplicates : ' || T_FINAL_TEXT);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(sqlerrm||chr(10)||dbms_utility.format_error_backtrace);
END;
/